diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-21 22:00:42 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-10-21 22:00:42 +0000 |
commit | 5e9746f520e6bbeafc36b8a23585b2e6117e1a7a (patch) | |
tree | 19d45b99d8cfaddc7598d6986cdd522463951cad /clang/lib/Sema/SemaExprCXX.cpp | |
parent | 00c03c5de7fd930da8fe1f9561037c4bc3987685 (diff) | |
download | bcm5719-llvm-5e9746f520e6bbeafc36b8a23585b2e6117e1a7a.tar.gz bcm5719-llvm-5e9746f520e6bbeafc36b8a23585b2e6117e1a7a.zip |
DR583, DR1512: Implement a rewrite to C++'s 'composite pointer type' rules.
This has two significant effects:
1) Direct relational comparisons between null pointer constants (0 and nullopt)
and pointers are now ill-formed. This was always the case for C, and it
appears that C++ only ever permitted by accident. For instance, cases like
nullptr < &a
are now rejected.
2) Comparisons and conditional operators between differently-cv-qualified
pointer types now work, and produce a composite type that both source
pointer types can convert to (when possible). For instance, comparison
between 'int **' and 'const int **' is now valid, and uses an intermediate
type of 'const int *const *'.
Clang previously supported #2 as an extension.
We do not accept the cases in #1 as an extension. I've tested a fair amount of
code to check that this doesn't break it, but if it turns out that someone is
relying on this, we can easily add it back as an extension.
This is a re-commit of r284800.
llvm-svn: 284890
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 40 |
1 files changed, 8 insertions, 32 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 49e25de2ac9..6ef7df13125 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -5410,7 +5410,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, nullptr, + LTy = FindCompositePointerType(QuestionLoc, LHS, RHS, /*ConvertArgs*/false); LTy = Context.getQualifiedType(LTy, Qs); @@ -5522,19 +5522,9 @@ 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. - 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(); - + QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS); + if (!Composite.isNull()) return Composite; - } // Similarly, attempt to find composite type of two objective-c pointers. Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc); @@ -5633,19 +5623,10 @@ 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: @@ -5738,8 +5719,7 @@ 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 (NonStandardCompositeType && - Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) + if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) NeedConstBefore = QualifierUnion.size(); QualifierUnion.push_back( @@ -5756,8 +5736,7 @@ 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 (NonStandardCompositeType && - Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) + if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers()) NeedConstBefore = QualifierUnion.size(); QualifierUnion.push_back( @@ -5808,16 +5787,13 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, } } - if (NeedConstBefore && NonStandardCompositeType) { + if (NeedConstBefore) { // 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. |