summaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/DeclSpec.cpp22
-rw-r--r--lib/Sema/SemaChecking.cpp165
-rw-r--r--lib/Sema/SemaDecl.cpp12
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp8
-rw-r--r--lib/Sema/SemaExpr.cpp115
-rw-r--r--lib/Sema/SemaExprCXX.cpp4
-rw-r--r--lib/Sema/SemaInit.cpp51
-rw-r--r--lib/Sema/SemaLookup.cpp2
-rw-r--r--lib/Sema/SemaOpenMP.cpp280
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();