diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 165 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaExceptionSpec.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 115 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 51 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 280 |
9 files changed, 452 insertions, 207 deletions
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index ea3872f42700..4adbb2b6af2a 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -987,10 +987,11 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) << getSpecifierName((TSW)TypeSpecWidth); - // vector bool long long requires VSX support. + // vector bool long long requires VSX support or ZVector. if ((TypeSpecWidth == TSW_longlong) && (!PP.getTargetInfo().hasFeature("vsx")) && - (!PP.getTargetInfo().hasFeature("power8-vector"))) + (!PP.getTargetInfo().hasFeature("power8-vector")) && + !PP.getLangOpts().ZVector) Diag(D, TSTLoc, diag::err_invalid_vector_long_long_decl_spec); // Elements of vector bool are interpreted as unsigned. (PIM 2.1) @@ -999,14 +1000,23 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP, const PrintingPoli TypeSpecSign = TSS_unsigned; } else if (TypeSpecType == TST_double) { // vector long double and vector long long double are never allowed. - // vector double is OK for Power7 and later. + // vector double is OK for Power7 and later, and ZVector. if (TypeSpecWidth == TSW_long || TypeSpecWidth == TSW_longlong) Diag(D, TSWLoc, diag::err_invalid_vector_long_double_decl_spec); - else if (!PP.getTargetInfo().hasFeature("vsx")) + else if (!PP.getTargetInfo().hasFeature("vsx") && + !PP.getLangOpts().ZVector) Diag(D, TSTLoc, diag::err_invalid_vector_double_decl_spec); + } else if (TypeSpecType == TST_float) { + // vector float is unsupported for ZVector. + if (PP.getLangOpts().ZVector) + Diag(D, TSTLoc, diag::err_invalid_vector_float_decl_spec); } else if (TypeSpecWidth == TSW_long) { - Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination) - << getSpecifierName((TST)TypeSpecType, Policy); + // vector long is unsupported for ZVector and deprecated for AltiVec. + if (PP.getLangOpts().ZVector) + Diag(D, TSWLoc, diag::err_invalid_vector_long_decl_spec); + else + Diag(D, TSWLoc, diag::warn_vector_long_decl_spec_combination) + << getSpecifierName((TST)TypeSpecType, Policy); } if (TypeAltiVecPixel) { diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d9d26e2af602..1a8ab6e209e5 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -8727,23 +8727,10 @@ static bool isSetterLikeSelector(Selector sel) { static Optional<int> GetNSMutableArrayArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - if (S.NSMutableArrayPointer.isNull()) { - IdentifierInfo *NSMutableArrayId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableArray); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableArrayId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - ObjCInterfaceDecl *InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (!InterfaceDecl) { - return None; - } - QualType NSMutableArrayObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableArrayPointer = - S.Context.getObjCObjectPointerType(NSMutableArrayObject); - } - - if (S.NSMutableArrayPointer != Message->getReceiverType()) { + bool IsMutableArray = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableArray); + if (!IsMutableArray) { return None; } @@ -8775,24 +8762,10 @@ static Optional<int> GetNSMutableArrayArgumentIndex(Sema &S, static Optional<int> GetNSMutableDictionaryArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - - if (S.NSMutableDictionaryPointer.isNull()) { - IdentifierInfo *NSMutableDictionaryId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableDictionary); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableDictionaryId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - ObjCInterfaceDecl *InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (!InterfaceDecl) { - return None; - } - QualType NSMutableDictionaryObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableDictionaryPointer = - S.Context.getObjCObjectPointerType(NSMutableDictionaryObject); - } - - if (S.NSMutableDictionaryPointer != Message->getReceiverType()) { + bool IsMutableDictionary = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableDictionary); + if (!IsMutableDictionary) { return None; } @@ -8820,63 +8793,14 @@ Optional<int> GetNSMutableDictionaryArgumentIndex(Sema &S, } static Optional<int> GetNSSetArgumentIndex(Sema &S, ObjCMessageExpr *Message) { - - ObjCInterfaceDecl *InterfaceDecl; - if (S.NSMutableSetPointer.isNull()) { - IdentifierInfo *NSMutableSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSMutableSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSMutableSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableSetPointer = - S.Context.getObjCObjectPointerType(NSMutableSetObject); - } - } - - if (S.NSCountedSetPointer.isNull()) { - IdentifierInfo *NSCountedSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSCountedSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSCountedSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSCountedSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSCountedSetPointer = - S.Context.getObjCObjectPointerType(NSCountedSetObject); - } - } - - if (S.NSMutableOrderedSetPointer.isNull()) { - IdentifierInfo *NSOrderedSetId = - S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSMutableOrderedSet); - NamedDecl *IF = S.LookupSingleName(S.TUScope, NSOrderedSetId, - Message->getLocStart(), - Sema::LookupOrdinaryName); - InterfaceDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF); - if (InterfaceDecl) { - QualType NSOrderedSetObject = - S.Context.getObjCInterfaceType(InterfaceDecl); - S.NSMutableOrderedSetPointer = - S.Context.getObjCObjectPointerType(NSOrderedSetObject); - } - } - - QualType ReceiverType = Message->getReceiverType(); - - bool IsMutableSet = !S.NSMutableSetPointer.isNull() && - ReceiverType == S.NSMutableSetPointer; - bool IsMutableOrderedSet = !S.NSMutableOrderedSetPointer.isNull() && - ReceiverType == S.NSMutableOrderedSetPointer; - bool IsCountedSet = !S.NSCountedSetPointer.isNull() && - ReceiverType == S.NSCountedSetPointer; - - if (!IsMutableSet && !IsMutableOrderedSet && !IsCountedSet) { + bool IsMutableSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableSet); + + bool IsMutableOrderedSet = S.NSAPIObj->isSubclassOfNSClass( + Message->getReceiverInterface(), + NSAPI::ClassId_NSMutableOrderedSet); + if (!IsMutableSet && !IsMutableOrderedSet) { return None; } @@ -8917,38 +8841,51 @@ void Sema::CheckObjCCircularContainer(ObjCMessageExpr *Message) { int ArgIndex = *ArgOpt; - Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); - if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { - Receiver = OE->getSourceExpr()->IgnoreImpCasts(); - } - Expr *Arg = Message->getArg(ArgIndex)->IgnoreImpCasts(); if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Arg)) { Arg = OE->getSourceExpr()->IgnoreImpCasts(); } - if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { + if (Message->getReceiverKind() == ObjCMessageExpr::SuperInstance) { if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { - if (ReceiverRE->getDecl() == ArgRE->getDecl()) { - ValueDecl *Decl = ReceiverRE->getDecl(); + if (ArgRE->isObjCSelfExpr()) { Diag(Message->getSourceRange().getBegin(), diag::warn_objc_circular_container) - << Decl->getName(); - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl->getName(); + << ArgRE->getDecl()->getName() << StringRef("super"); } } - } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { - if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { - if (IvarRE->getDecl() == IvarArgRE->getDecl()) { - ObjCIvarDecl *Decl = IvarRE->getDecl(); - Diag(Message->getSourceRange().getBegin(), - diag::warn_objc_circular_container) - << Decl->getName(); - Diag(Decl->getLocation(), - diag::note_objc_circular_container_declared_here) - << Decl->getName(); + } else { + Expr *Receiver = Message->getInstanceReceiver()->IgnoreImpCasts(); + + if (OpaqueValueExpr *OE = dyn_cast<OpaqueValueExpr>(Receiver)) { + Receiver = OE->getSourceExpr()->IgnoreImpCasts(); + } + + if (DeclRefExpr *ReceiverRE = dyn_cast<DeclRefExpr>(Receiver)) { + if (DeclRefExpr *ArgRE = dyn_cast<DeclRefExpr>(Arg)) { + if (ReceiverRE->getDecl() == ArgRE->getDecl()) { + ValueDecl *Decl = ReceiverRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl->getName() << Decl->getName(); + if (!ArgRE->isObjCSelfExpr()) { + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl->getName(); + } + } + } + } else if (ObjCIvarRefExpr *IvarRE = dyn_cast<ObjCIvarRefExpr>(Receiver)) { + if (ObjCIvarRefExpr *IvarArgRE = dyn_cast<ObjCIvarRefExpr>(Arg)) { + if (IvarRE->getDecl() == IvarArgRE->getDecl()) { + ObjCIvarDecl *Decl = IvarRE->getDecl(); + Diag(Message->getSourceRange().getBegin(), + diag::warn_objc_circular_container) + << Decl->getName() << Decl->getName(); + Diag(Decl->getLocation(), + diag::note_objc_circular_container_declared_here) + << Decl->getName(); + } } } } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 99d4a79c4669..c694a20319b0 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5381,10 +5381,9 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr; if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) { - // If the declaration hasn't been used yet, allow with a warning for - // free functions and global variables. + // Allow with a warning for free functions and global variables. bool JustWarn = false; - if (!OldDecl->isUsed() && !OldDecl->isCXXClassMember()) { + if (!OldDecl->isCXXClassMember()) { auto *VD = dyn_cast<VarDecl>(OldDecl); if (VD && !VD->getDescribedVarTemplate()) JustWarn = true; @@ -5393,6 +5392,13 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, JustWarn = true; } + // We cannot change a declaration that's been used because IR has already + // been emitted. Dllimported functions will still work though (modulo + // address equality) as they can use the thunk. + if (OldDecl->isUsed()) + if (!isa<FunctionDecl>(OldDecl) || !NewImportAttr) + JustWarn = false; + unsigned DiagID = JustWarn ? diag::warn_attribute_dll_redeclaration : diag::err_attribute_dll_redeclaration; S.Diag(NewDecl->getLocation(), DiagID) diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 094187025df0..2cf02b484cb4 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -161,7 +161,13 @@ Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { else InstantiateExceptionSpec(Loc, SourceDecl); - return SourceDecl->getType()->castAs<FunctionProtoType>(); + const FunctionProtoType *Proto = + SourceDecl->getType()->castAs<FunctionProtoType>(); + if (Proto->getExceptionSpecType() == clang::EST_Unparsed) { + Diag(Loc, diag::err_exception_spec_not_parsed); + Proto = nullptr; + } + return Proto; } void diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1ae983cad227..6499cb5d19eb 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4949,6 +4949,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, if (!Result.isUsable()) return ExprError(); TheCall = dyn_cast<CallExpr>(Result.get()); if (!TheCall) return Result; + Args = ArrayRef<Expr *>(TheCall->getArgs(), TheCall->getNumArgs()); } // Bail out early if calling a builtin with custom typechecking. @@ -5518,7 +5519,7 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, // i.e. all the elements are integer constants. ParenExpr *PE = dyn_cast<ParenExpr>(CastExpr); ParenListExpr *PLE = dyn_cast<ParenListExpr>(CastExpr); - if ((getLangOpts().AltiVec || getLangOpts().OpenCL) + if ((getLangOpts().AltiVec || getLangOpts().ZVector || getLangOpts().OpenCL) && castType->isVectorType() && (PE || PLE)) { if (PLE && PLE->getNumExprs() == 0) { Diag(PLE->getExprLoc(), diag::err_altivec_empty_initializer); @@ -6075,7 +6076,9 @@ OpenCLCheckVectorConditional(Sema &S, ExprResult &Cond, if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) { QualType VecResTy = S.CheckVectorOperands(LHS, RHS, QuestionLoc, - /*isCompAssign*/false); + /*isCompAssign*/false, + /*AllowBothBool*/true, + /*AllowBoolConversions*/false); if (VecResTy.isNull()) return QualType(); // The result type must match the condition type as specified in // OpenCL v1.1 s6.11.6. @@ -6126,7 +6129,9 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // Now check the two expressions. if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) - return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); + return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false, + /*AllowBothBool*/true, + /*AllowBoolConversions*/false); QualType ResTy = UsualArithmeticConversions(LHS, RHS); if (LHS.isInvalid() || RHS.isInvalid()) @@ -7267,7 +7272,9 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar, } QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, - SourceLocation Loc, bool IsCompAssign) { + SourceLocation Loc, bool IsCompAssign, + bool AllowBothBool, + bool AllowBoolConversions) { if (!IsCompAssign) { LHS = DefaultFunctionArrayLvalueConversion(LHS.get()); if (LHS.isInvalid()) @@ -7282,14 +7289,21 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, QualType LHSType = LHS.get()->getType().getUnqualifiedType(); QualType RHSType = RHS.get()->getType().getUnqualifiedType(); - // If the vector types are identical, return. - if (Context.hasSameType(LHSType, RHSType)) - return LHSType; - const VectorType *LHSVecType = LHSType->getAs<VectorType>(); const VectorType *RHSVecType = RHSType->getAs<VectorType>(); assert(LHSVecType || RHSVecType); + // AltiVec-style "vector bool op vector bool" combinations are allowed + // for some operators but not others. + if (!AllowBothBool && + LHSVecType && LHSVecType->getVectorKind() == VectorType::AltiVecBool && + RHSVecType && RHSVecType->getVectorKind() == VectorType::AltiVecBool) + return InvalidOperands(Loc, LHS, RHS); + + // If the vector types are identical, return. + if (Context.hasSameType(LHSType, RHSType)) + return LHSType; + // If we have compatible AltiVec and GCC vector types, use the AltiVec type. if (LHSVecType && RHSVecType && Context.areCompatibleVectorTypes(LHSType, RHSType)) { @@ -7303,6 +7317,28 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return RHSType; } + // AllowBoolConversions says that bool and non-bool AltiVec vectors + // can be mixed, with the result being the non-bool type. The non-bool + // operand must have integer element type. + if (AllowBoolConversions && LHSVecType && RHSVecType && + LHSVecType->getNumElements() == RHSVecType->getNumElements() && + (Context.getTypeSize(LHSVecType->getElementType()) == + Context.getTypeSize(RHSVecType->getElementType()))) { + if (LHSVecType->getVectorKind() == VectorType::AltiVecVector && + LHSVecType->getElementType()->isIntegerType() && + RHSVecType->getVectorKind() == VectorType::AltiVecBool) { + RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast); + return LHSType; + } + if (!IsCompAssign && + LHSVecType->getVectorKind() == VectorType::AltiVecBool && + RHSVecType->getVectorKind() == VectorType::AltiVecVector && + RHSVecType->getElementType()->isIntegerType()) { + LHS = ImpCastExprToType(LHS.get(), RHSType, CK_BitCast); + return RHSType; + } + } + // If there's an ext-vector type and a scalar, try to convert the scalar to // the vector element type and splat. if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) { @@ -7391,7 +7427,9 @@ QualType Sema::CheckMultiplyDivideOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) - return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); + return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, + /*AllowBothBool*/getLangOpts().AltiVec, + /*AllowBoolConversions*/false); QualType compType = UsualArithmeticConversions(LHS, RHS, IsCompAssign); if (LHS.isInvalid() || RHS.isInvalid()) @@ -7420,7 +7458,9 @@ QualType Sema::CheckRemainderOperands( RHS.get()->getType()->isVectorType()) { if (LHS.get()->getType()->hasIntegerRepresentation() && RHS.get()->getType()->hasIntegerRepresentation()) - return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); + return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, + /*AllowBothBool*/getLangOpts().AltiVec, + /*AllowBoolConversions*/false); return InvalidOperands(Loc, LHS, RHS); } @@ -7706,7 +7746,10 @@ QualType Sema::CheckAdditionOperands( // C99 6.5.6 if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) { - QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy); + QualType compType = CheckVectorOperands( + LHS, RHS, Loc, CompLHSTy, + /*AllowBothBool*/getLangOpts().AltiVec, + /*AllowBoolConversions*/getLangOpts().ZVector); if (CompLHSTy) *CompLHSTy = compType; return compType; } @@ -7781,7 +7824,10 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS, if (LHS.get()->getType()->isVectorType() || RHS.get()->getType()->isVectorType()) { - QualType compType = CheckVectorOperands(LHS, RHS, Loc, CompLHSTy); + QualType compType = CheckVectorOperands( + LHS, RHS, Loc, CompLHSTy, + /*AllowBothBool*/getLangOpts().AltiVec, + /*AllowBoolConversions*/getLangOpts().ZVector); if (CompLHSTy) *CompLHSTy = compType; return compType; } @@ -8023,7 +8069,21 @@ QualType Sema::CheckShiftOperands(ExprResult &LHS, ExprResult &RHS, RHS.get()->getType()->isVectorType()) { if (LangOpts.OpenCL) return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); - return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); + if (LangOpts.ZVector) { + // The shift operators for the z vector extensions work basically + // like OpenCL shifts, except that neither the LHS nor the RHS is + // allowed to be a "vector bool". + if (auto LHSVecType = LHS.get()->getType()->getAs<VectorType>()) + if (LHSVecType->getVectorKind() == VectorType::AltiVecBool) + return InvalidOperands(Loc, LHS, RHS); + if (auto RHSVecType = RHS.get()->getType()->getAs<VectorType>()) + if (RHSVecType->getVectorKind() == VectorType::AltiVecBool) + return InvalidOperands(Loc, LHS, RHS); + return checkOpenCLVectorShift(*this, LHS, RHS, Loc, IsCompAssign); + } + return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, + /*AllowBothBool*/true, + /*AllowBoolConversions*/false); } // Shifts don't perform usual arithmetic conversions, they just do integer @@ -8797,7 +8857,9 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, bool IsRelational) { // Check to make sure we're operating on vectors of the same type and width, // Allowing one side to be a scalar of element type. - QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false); + QualType vType = CheckVectorOperands(LHS, RHS, Loc, /*isCompAssign*/false, + /*AllowBothBool*/true, + /*AllowBoolConversions*/getLangOpts().ZVector); if (vType.isNull()) return vType; @@ -8805,7 +8867,8 @@ QualType Sema::CheckVectorCompareOperands(ExprResult &LHS, ExprResult &RHS, // If AltiVec, the comparison results in a numeric type, i.e. // bool for C++, int for C - if (vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector) + if (getLangOpts().AltiVec && + vType->getAs<VectorType>()->getVectorKind() == VectorType::AltiVecVector) return Context.getLogicalOperationType(); // For non-floating point types, check for self-comparisons of the form @@ -8839,7 +8902,9 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc) { // Ensure that either both operands are of the same vector type, or // one operand is of a vector type and the other is of its element type. - QualType vType = CheckVectorOperands(LHS, RHS, Loc, false); + QualType vType = CheckVectorOperands(LHS, RHS, Loc, false, + /*AllowBothBool*/true, + /*AllowBoolConversions*/false); if (vType.isNull()) return InvalidOperands(Loc, LHS, RHS); if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 && @@ -8857,8 +8922,9 @@ inline QualType Sema::CheckBitwiseOperands( RHS.get()->getType()->isVectorType()) { if (LHS.get()->getType()->hasIntegerRepresentation() && RHS.get()->getType()->hasIntegerRepresentation()) - return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign); - + return CheckVectorOperands(LHS, RHS, Loc, IsCompAssign, + /*AllowBothBool*/true, + /*AllowBoolConversions*/getLangOpts().ZVector); return InvalidOperands(Loc, LHS, RHS); } @@ -9472,6 +9538,10 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, IsInc, IsPrefix); } else if (S.getLangOpts().AltiVec && ResType->isVectorType()) { // OK! ( C/C++ Language Extensions for CBEA(Version 2.6) 10.3 ) + } else if (S.getLangOpts().ZVector && ResType->isVectorType() && + (ResType->getAs<VectorType>()->getVectorKind() != + VectorType::AltiVecBool)) { + // The z vector extensions allow ++ and -- for non-bool vectors. } else if(S.getLangOpts().OpenCL && ResType->isVectorType() && ResType->getAs<VectorType>()->getElementType()->isIntegerType()) { // OpenCL V1.2 6.3 says dec/inc ops operate on integer vector types. @@ -10552,8 +10622,13 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = Input.get()->getType(); if (resultType->isDependentType()) break; - if (resultType->isArithmeticType() || // C99 6.5.3.3p1 - resultType->isVectorType()) + if (resultType->isArithmeticType()) // C99 6.5.3.3p1 + break; + else if (resultType->isVectorType() && + // The z vector extensions don't allow + or - with bool vectors. + (!Context.getLangOpts().ZVector || + resultType->getAs<VectorType>()->getVectorKind() != + VectorType::AltiVecBool)) break; else if (getLangOpts().CPlusPlus && // C++ [expr.unary.op]p6 Opc == UO_Plus && diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 6608d7c1f061..01966d569a11 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4950,7 +4950,9 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // Extension: conditional operator involving vector types. if (LTy->isVectorType() || RTy->isVectorType()) - return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false); + return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/false, + /*AllowBothBool*/true, + /*AllowBoolConversions*/false); // -- The second and third operands have arithmetic or enumeration type; // the usual arithmetic conversions are performed to bring them to a diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index f0f7cb93d339..adec512693f3 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2372,14 +2372,12 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, return true; } } else { - // Make sure the bit-widths and signedness match. - if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth()) - DesignatedEndIndex - = DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth()); - else if (DesignatedStartIndex.getBitWidth() < - DesignatedEndIndex.getBitWidth()) - DesignatedStartIndex - = DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth()); + unsigned DesignatedIndexBitWidth = + ConstantArrayType::getMaxSizeBits(SemaRef.Context); + DesignatedStartIndex = + DesignatedStartIndex.extOrTrunc(DesignatedIndexBitWidth); + DesignatedEndIndex = + DesignatedEndIndex.extOrTrunc(DesignatedIndexBitWidth); DesignatedStartIndex.setIsUnsigned(true); DesignatedEndIndex.setIsUnsigned(true); } @@ -5928,6 +5926,9 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr, if (!InitExpr) return; + if (!S.ActiveTemplateInstantiations.empty()) + return; + QualType DestType = InitExpr->getType(); if (!DestType->isRecordType()) return; @@ -5943,24 +5944,6 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr, return; InitExpr = CCE->getArg(0)->IgnoreImpCasts(); - - // Remove implicit temporary and constructor nodes. - if (const MaterializeTemporaryExpr *MTE = - dyn_cast<MaterializeTemporaryExpr>(InitExpr)) { - InitExpr = MTE->GetTemporaryExpr()->IgnoreImpCasts(); - while (const CXXConstructExpr *CCE = - dyn_cast<CXXConstructExpr>(InitExpr)) { - if (isa<CXXTemporaryObjectExpr>(CCE)) - return; - if (CCE->getNumArgs() == 0) - return; - if (CCE->getNumArgs() > 1 && !isa<CXXDefaultArgExpr>(CCE->getArg(1))) - return; - InitExpr = CCE->getArg(0); - } - InitExpr = InitExpr->IgnoreImpCasts(); - DiagID = diag::warn_redundant_move_on_return; - } } // Find the std::move call and get the argument. @@ -5985,14 +5968,20 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr, if (!VD || !VD->hasLocalStorage()) return; - if (!VD->getType()->isRecordType()) + QualType SourceType = VD->getType(); + if (!SourceType->isRecordType()) return; - if (DiagID == 0) { - DiagID = S.Context.hasSameUnqualifiedType(DestType, VD->getType()) - ? diag::warn_pessimizing_move_on_return - : diag::warn_redundant_move_on_return; + if (!S.Context.hasSameUnqualifiedType(DestType, SourceType)) { + return; } + + // If we're returning a function parameter, copy elision + // is not possible. + if (isa<ParmVarDecl>(VD)) + DiagID = diag::warn_redundant_move_on_return; + else + DiagID = diag::warn_pessimizing_move_on_return; } else { DiagID = diag::warn_pessimizing_move_on_initialization; const Expr *ArgStripped = Arg->IgnoreImplicit()->IgnoreParens(); diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 3fd1f21ba3fd..2e7f89191580 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -4245,7 +4245,7 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( // Don't try to correct the identifier "vector" when in AltiVec mode. // TODO: Figure out why typo correction misbehaves in this case, fix it, and // remove this workaround. - if (getLangOpts().AltiVec && Typo->isStr("vector")) + if ((getLangOpts().AltiVec || getLangOpts().ZVector) && Typo->isStr("vector")) return nullptr; // Provide a stop gap for files that are just seriously broken. Trying diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 4030d9e66e02..ca67a1c0bf24 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -12,6 +12,7 @@ /// //===----------------------------------------------------------------------===// +#include "TreeTransform.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/Decl.h" @@ -120,6 +121,7 @@ private: /// from current directive. OpenMPClauseKind ClauseKindMode; Sema &SemaRef; + bool ForceCapturing; typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; @@ -130,11 +132,15 @@ private: public: explicit DSAStackTy(Sema &S) - : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S) {} + : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S), + ForceCapturing(false) {} bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } + bool isForceVarCapturing() const { return ForceCapturing; } + void setForceVarCapturing(bool V) { ForceCapturing = V; } + void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc) { Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); @@ -652,10 +658,13 @@ void Sema::InitDataSharingAttributesStack() { bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { assert(LangOpts.OpenMP && "OpenMP is not allowed"); VD = VD->getCanonicalDecl(); - if (DSAStack->getCurrentDirective() != OMPD_unknown) { + if (DSAStack->getCurrentDirective() != OMPD_unknown && + (!DSAStack->isClauseParsingMode() || + DSAStack->getParentDirective() != OMPD_unknown)) { if (DSAStack->isLoopControlVariable(VD) || (VD->hasLocalStorage() && - isParallelOrTaskRegion(DSAStack->getCurrentDirective()))) + isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || + DSAStack->isForceVarCapturing()) return true; auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode()); if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) @@ -1350,13 +1359,18 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, // This is required for proper codegen. for (auto *Clause : Clauses) { if (isOpenMPPrivate(Clause->getClauseKind()) || - Clause->getClauseKind() == OMPC_copyprivate) { + Clause->getClauseKind() == OMPC_copyprivate || + (getLangOpts().OpenMPUseTLS && + getASTContext().getTargetInfo().isTLSSupported() && + Clause->getClauseKind() == OMPC_copyin)) { + DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); // Mark all variables in private list clauses as used in inner region. for (auto *VarRef : Clause->children()) { if (auto *E = cast_or_null<Expr>(VarRef)) { MarkDeclarationsReferencedInExpr(E); } } + DSAStack->setForceVarCapturing(/*V=*/false); } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && Clause->getClauseKind() == OMPC_schedule) { // Mark all variables in private list clauses as used in inner region. @@ -2262,6 +2276,22 @@ bool OpenMPIterationSpaceChecker::Dependent() const { (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); } +template <typename T> +static T *getExprAsWritten(T *E) { + if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) + E = ExprTemp->getSubExpr(); + + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) + E = MTE->GetTemporaryExpr(); + + while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) + E = Binder->getSubExpr(); + + if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) + E = ICE->getSubExprAsWritten(); + return E->IgnoreParens(); +} + bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB) { @@ -2272,6 +2302,12 @@ bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, return true; Var = NewVar; VarRef = NewVarRefExpr; + if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) + if (const CXXConstructorDecl *Ctor = CE->getConstructor()) + if ((Ctor->isCopyOrMoveConstructor() || + Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && + CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) + NewLB = CE->getArg(0)->IgnoreParenImpCasts(); LB = NewLB; return false; } @@ -2402,11 +2438,12 @@ bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { static const VarDecl *GetInitVarDecl(const Expr *E) { if (!E) return nullptr; - E = E->IgnoreParenImpCasts(); + E = getExprAsWritten(E); if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) if (const CXXConstructorDecl *Ctor = CE->getConstructor()) - if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && - CE->getArg(0) != nullptr) + if ((Ctor->isCopyOrMoveConstructor() || + Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && + CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) E = CE->getArg(0)->IgnoreParenImpCasts(); auto DRE = dyn_cast_or_null<DeclRefExpr>(E); if (!DRE) @@ -2425,7 +2462,7 @@ bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; return true; } - S = S->IgnoreParenImpCasts(); + S = getExprAsWritten(S); SourceLocation CondLoc = S->getLocStart(); if (auto BO = dyn_cast<BinaryOperator>(S)) { if (BO->isRelationalOp()) { @@ -2565,20 +2602,85 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { return true; } +namespace { +// Transform variables declared in GNU statement expressions to new ones to +// avoid crash on codegen. +class TransformToNewDefs : public TreeTransform<TransformToNewDefs> { + typedef TreeTransform<TransformToNewDefs> BaseTransform; + +public: + TransformToNewDefs(Sema &SemaRef) : BaseTransform(SemaRef) {} + + Decl *TransformDefinition(SourceLocation Loc, Decl *D) { + if (auto *VD = cast<VarDecl>(D)) + if (!isa<ParmVarDecl>(D) && !isa<VarTemplateSpecializationDecl>(D) && + !isa<ImplicitParamDecl>(D)) { + auto *NewVD = VarDecl::Create( + SemaRef.Context, VD->getDeclContext(), VD->getLocStart(), + VD->getLocation(), VD->getIdentifier(), VD->getType(), + VD->getTypeSourceInfo(), VD->getStorageClass()); + NewVD->setTSCSpec(VD->getTSCSpec()); + NewVD->setInit(VD->getInit()); + NewVD->setInitStyle(VD->getInitStyle()); + NewVD->setExceptionVariable(VD->isExceptionVariable()); + NewVD->setNRVOVariable(VD->isNRVOVariable()); + NewVD->setCXXForRangeDecl(VD->isInExternCXXContext()); + NewVD->setConstexpr(VD->isConstexpr()); + NewVD->setInitCapture(VD->isInitCapture()); + NewVD->setPreviousDeclInSameBlockScope( + VD->isPreviousDeclInSameBlockScope()); + VD->getDeclContext()->addHiddenDecl(NewVD); + transformedLocalDecl(VD, NewVD); + return NewVD; + } + return BaseTransform::TransformDefinition(Loc, D); + } + + ExprResult TransformDeclRefExpr(DeclRefExpr *E) { + if (auto *NewD = TransformDecl(E->getExprLoc(), E->getDecl())) + if (E->getDecl() != NewD) { + NewD->setReferenced(); + NewD->markUsed(SemaRef.Context); + return DeclRefExpr::Create( + SemaRef.Context, E->getQualifierLoc(), E->getTemplateKeywordLoc(), + cast<ValueDecl>(NewD), E->refersToEnclosingVariableOrCapture(), + E->getNameInfo(), E->getType(), E->getValueKind()); + } + return BaseTransform::TransformDeclRefExpr(E); + } +}; +} + /// \brief Build the expression to calculate the number of iterations. Expr * OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, const bool LimitedType) const { + TransformToNewDefs Transform(SemaRef); ExprResult Diff; - if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || + auto VarType = Var->getType().getNonReferenceType(); + if (VarType->isIntegerType() || VarType->isPointerType() || SemaRef.getLangOpts().CPlusPlus) { // Upper - Lower - Expr *Upper = TestIsLessOp ? UB : LB; - Expr *Lower = TestIsLessOp ? LB : UB; + auto *UBExpr = TestIsLessOp ? UB : LB; + auto *LBExpr = TestIsLessOp ? LB : UB; + Expr *Upper = Transform.TransformExpr(UBExpr).get(); + Expr *Lower = Transform.TransformExpr(LBExpr).get(); + if (!Upper || !Lower) + return nullptr; + Upper = SemaRef.PerformImplicitConversion(Upper, UBExpr->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true) + .get(); + Lower = SemaRef.PerformImplicitConversion(Lower, LBExpr->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true) + .get(); + if (!Upper || !Lower) + return nullptr; Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); - if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { + if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { // BuildBinOp already emitted error, this one is to point user to upper // and lower bound, and to tell what is passed to 'operator-'. SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) @@ -2599,8 +2701,15 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // Upper - Lower [- 1] + Step - Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), - Step->IgnoreImplicit()); + auto NewStep = Transform.TransformExpr(Step->IgnoreImplicit()); + if (NewStep.isInvalid()) + return nullptr; + NewStep = SemaRef.PerformImplicitConversion( + NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewStep.isInvalid()) + return nullptr; + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; @@ -2610,15 +2719,35 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, return nullptr; // (Upper - Lower [- 1] + Step) / Step - Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), - Step->IgnoreImplicit()); + NewStep = Transform.TransformExpr(Step->IgnoreImplicit()); + if (NewStep.isInvalid()) + return nullptr; + NewStep = SemaRef.PerformImplicitConversion( + NewStep.get(), Step->IgnoreImplicit()->getType(), Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewStep.isInvalid()) + return nullptr; + Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); if (!Diff.isUsable()) return nullptr; // OpenMP runtime requires 32-bit or 64-bit loop variables. + QualType Type = Diff.get()->getType(); + auto &C = SemaRef.Context; + bool UseVarType = VarType->hasIntegerRepresentation() && + C.getTypeSize(Type) > C.getTypeSize(VarType); + if (!Type->isIntegerType() || UseVarType) { + unsigned NewSize = + UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); + bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() + : Type->hasSignedIntegerRepresentation(); + Type = C.getIntTypeForBitwidth(NewSize, IsSigned); + Diff = SemaRef.PerformImplicitConversion( + Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); + if (!Diff.isUsable()) + return nullptr; + } if (LimitedType) { - auto &C = SemaRef.Context; - QualType Type = Diff.get()->getType(); unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; if (NewSize != C.getTypeSize(Type)) { if (NewSize < C.getTypeSize(Type)) { @@ -2627,7 +2756,8 @@ OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, << InitSrcRange << ConditionSrcRange; } QualType NewType = C.getIntTypeForBitwidth( - NewSize, Type->hasSignedIntegerRepresentation()); + NewSize, Type->hasSignedIntegerRepresentation() || + C.getTypeSize(Type) < NewSize); Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, Sema::AA_Converting, true); if (!Diff.isUsable()) @@ -2642,10 +2772,29 @@ Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { // Try to build LB <op> UB, where <op> is <, >, <=, or >=. bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); + TransformToNewDefs Transform(SemaRef); + + auto NewLB = Transform.TransformExpr(LB); + auto NewUB = Transform.TransformExpr(UB); + if (NewLB.isInvalid() || NewUB.isInvalid()) + return Cond; + NewLB = SemaRef.PerformImplicitConversion(NewLB.get(), LB->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true); + NewUB = SemaRef.PerformImplicitConversion(NewUB.get(), UB->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewLB.isInvalid() || NewUB.isInvalid()) + return Cond; auto CondExpr = SemaRef.BuildBinOp( S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) : (TestIsStrictOp ? BO_GT : BO_GE), - LB, UB); + NewLB.get(), NewUB.get()); + if (CondExpr.isUsable()) { + CondExpr = SemaRef.PerformImplicitConversion( + CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, + /*AllowExplicit=*/true); + } SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); // Otherwise use original loop conditon and evaluate it in runtime. return CondExpr.isUsable() ? CondExpr.get() : Cond; @@ -2835,6 +2984,31 @@ static bool CheckOpenMPIterationSpace( return HasErrors; } +/// \brief Build 'VarRef = Start. +static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, + ExprResult VarRef, ExprResult Start) { + TransformToNewDefs Transform(SemaRef); + // Build 'VarRef = Start. + auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit()); + if (NewStart.isInvalid()) + return ExprError(); + NewStart = SemaRef.PerformImplicitConversion( + NewStart.get(), Start.get()->IgnoreImplicit()->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewStart.isInvalid()) + return ExprError(); + NewStart = SemaRef.PerformImplicitConversion( + NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, + /*AllowExplicit=*/true); + if (!NewStart.isUsable()) + return ExprError(); + + auto Init = + SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); + return Init; +} + /// \brief Build 'VarRef = Start + Iter * Step'. static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, @@ -2846,14 +3020,33 @@ static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, !Step.isUsable()) return ExprError(); - ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), - Step.get()->IgnoreImplicit()); + TransformToNewDefs Transform(SemaRef); + auto NewStep = Transform.TransformExpr(Step.get()->IgnoreImplicit()); + if (NewStep.isInvalid()) + return ExprError(); + NewStep = SemaRef.PerformImplicitConversion( + NewStep.get(), Step.get()->IgnoreImplicit()->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewStep.isInvalid()) + return ExprError(); + ExprResult Update = + SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); if (!Update.isUsable()) return ExprError(); // Build 'VarRef = Start + Iter * Step'. + auto NewStart = Transform.TransformExpr(Start.get()->IgnoreImplicit()); + if (NewStart.isInvalid()) + return ExprError(); + NewStart = SemaRef.PerformImplicitConversion( + NewStart.get(), Start.get()->IgnoreImplicit()->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true); + if (NewStart.isInvalid()) + return ExprError(); Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), - Start.get()->IgnoreImplicit(), Update.get()); + NewStart.get(), Update.get()); if (!Update.isUsable()) return ExprError(); @@ -2964,8 +3157,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, // true). auto PreCond = ExprResult(IterSpaces[0].PreCond); auto N0 = IterSpaces[0].NumIterations; - ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); - ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); + ExprResult LastIteration32 = WidenIterationCount( + 32 /* Bits */, SemaRef.PerformImplicitConversion( + N0->IgnoreImpCasts(), N0->getType(), + Sema::AA_Converting, /*AllowExplicit=*/true) + .get(), + SemaRef); + ExprResult LastIteration64 = WidenIterationCount( + 64 /* Bits */, SemaRef.PerformImplicitConversion( + N0->IgnoreImpCasts(), N0->getType(), + Sema::AA_Converting, /*AllowExplicit=*/true) + .get(), + SemaRef); if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) return NestedLoopCount; @@ -2982,11 +3185,19 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, auto N = IterSpaces[Cnt].NumIterations; AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; if (LastIteration32.isUsable()) - LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, - LastIteration32.get(), N); + LastIteration32 = SemaRef.BuildBinOp( + CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), + SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true) + .get()); if (LastIteration64.isUsable()) - LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, - LastIteration64.get(), N); + LastIteration64 = SemaRef.BuildBinOp( + CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), + SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), + Sema::AA_Converting, + /*AllowExplicit=*/true) + .get()); } // Choose either the 32-bit or 64-bit version. @@ -3147,6 +3358,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, // Build updates and final values of the loop counters. bool HasErrors = false; Built.Counters.resize(NestedLoopCount); + Built.Inits.resize(NestedLoopCount); Built.Updates.resize(NestedLoopCount); Built.Finals.resize(NestedLoopCount); { @@ -3180,6 +3392,12 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), /*RefersToCapture=*/true); + ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, + IS.CounterInit); + if (!Init.isUsable()) { + HasErrors = true; + break; + } ExprResult Update = BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); @@ -3219,6 +3437,7 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, } // Save results Built.Counters[Cnt] = IS.CounterVar; + Built.Inits[Cnt] = Init.get(); Built.Updates[Cnt] = Update.get(); Built.Finals[Cnt] = Final.get(); } @@ -3231,7 +3450,8 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, Built.IterationVarRef = IV.get(); Built.LastIteration = LastIteration.get(); Built.NumIterations = NumIterations.get(); - Built.CalcLastIteration = CalcLastIteration.get(); + Built.CalcLastIteration = + SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); Built.Cond = Cond.get(); Built.Init = Init.get(); |