summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 66705f88f9e..83474cb7f83 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -5399,7 +5399,7 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// exception specifications, if any.
if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) {
Qualifiers Qs = LTy.getQualifiers();
- LTy = FindCompositePointerType(QuestionLoc, LHS, RHS,
+ LTy = FindCompositePointerType(QuestionLoc, LHS, RHS, nullptr,
/*ConvertArgs*/false);
LTy = Context.getQualifiedType(LTy, Qs);
@@ -5511,9 +5511,19 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// performed to bring them to a common type, whose cv-qualification
// shall match the cv-qualification of either the second or the third
// operand. The result is of the common type.
- QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS);
- if (!Composite.isNull())
+ bool NonStandardCompositeType = false;
+ QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS,
+ isSFINAEContext() ? nullptr
+ : &NonStandardCompositeType);
+ if (!Composite.isNull()) {
+ if (NonStandardCompositeType)
+ Diag(QuestionLoc,
+ diag::ext_typecheck_cond_incompatible_operands_nonstandard)
+ << LTy << RTy << Composite
+ << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+
return Composite;
+ }
// Similarly, attempt to find composite type of two objective-c pointers.
Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
@@ -5612,10 +5622,19 @@ mergeExceptionSpecs(Sema &S, FunctionProtoType::ExceptionSpecInfo ESI1,
/// \param Loc The location of the operator requiring these two expressions to
/// be converted to the composite pointer type.
///
+/// If \p NonStandardCompositeType is non-NULL, then we are permitted to find
+/// a non-standard (but still sane) composite type to which both expressions
+/// can be converted. When such a type is chosen, \c *NonStandardCompositeType
+/// will be set true.
+///
/// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type.
QualType Sema::FindCompositePointerType(SourceLocation Loc,
Expr *&E1, Expr *&E2,
+ bool *NonStandardCompositeType,
bool ConvertArgs) {
+ if (NonStandardCompositeType)
+ *NonStandardCompositeType = false;
+
assert(getLangOpts().CPlusPlus && "This function assumes C++");
// C++1z [expr]p14:
@@ -5708,7 +5727,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// If we're allowed to create a non-standard composite type, keep track
// of where we need to fill in additional 'const' qualifiers.
- if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+ if (NonStandardCompositeType &&
+ Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
NeedConstBefore = QualifierUnion.size();
QualifierUnion.push_back(
@@ -5725,7 +5745,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
// If we're allowed to create a non-standard composite type, keep track
// of where we need to fill in additional 'const' qualifiers.
- if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+ if (NonStandardCompositeType &&
+ Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
NeedConstBefore = QualifierUnion.size();
QualifierUnion.push_back(
@@ -5776,13 +5797,16 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
}
}
- if (NeedConstBefore) {
+ if (NeedConstBefore && NonStandardCompositeType) {
// Extension: Add 'const' to qualifiers that come before the first qualifier
// mismatch, so that our (non-standard!) composite type meets the
// requirements of C++ [conv.qual]p4 bullet 3.
- for (unsigned I = 0; I != NeedConstBefore; ++I)
- if ((QualifierUnion[I] & Qualifiers::Const) == 0)
+ for (unsigned I = 0; I != NeedConstBefore; ++I) {
+ if ((QualifierUnion[I] & Qualifiers::Const) == 0) {
QualifierUnion[I] = QualifierUnion[I] | Qualifiers::Const;
+ *NonStandardCompositeType = true;
+ }
+ }
}
// Rewrap the composites as pointers or member pointers with the union CVRs.
OpenPOWER on IntegriCloud