diff options
author | cor3ntin <corentinjabot@gmail.com> | 2024-07-22 15:57:22 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-22 15:57:22 +0200 |
commit | 3c459cfcaebdaf7cabac33a0e18bf6588cef4cdb (patch) | |
tree | 7067c8550332cfac4ee132d769ad7a53368eb7ac /clang/lib | |
parent | bc4c3bf1b75fec183e2616d6688aa155d6aada74 (diff) | |
download | llvm-3c459cfcaebdaf7cabac33a0e18bf6588cef4cdb.zip llvm-3c459cfcaebdaf7cabac33a0e18bf6588cef4cdb.tar.gz llvm-3c459cfcaebdaf7cabac33a0e18bf6588cef4cdb.tar.bz2 |
[Clang] Fix handling of qualified id-expressions in unevaluated contexts (#99807)
In #89713, we made qualified, parenthesized id-expression ill-formed in
and address of expressions.
The expected behavior should instead be to form a pointer (rather than a
pointer to member)
The fix has been suggested by @zwuis and the tests by
@hubert-reinterpretcast.
It is worth pointing out that some of these tests seem rejected by all
compilers, however the tests do seem correct.
Fixes #89713
Fixes #40906
---------
Co-authored-by: YanzuoLiu <zwuis@outlook.com>
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8d24e34..1a441d9 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14117,7 +14117,14 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { // Okay: we can take the address of a field. // Could be a pointer to member, though, if there is an explicit // scope qualifier for the class. - if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier()) { + + // [C++26] [expr.prim.id.general] + // If an id-expression E denotes a non-static non-type member + // of some class C [...] and if E is a qualified-id, E is + // not the un-parenthesized operand of the unary & operator [...] + // the id-expression is transformed into a class member access expression. + if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() && + !isa<ParenExpr>(OrigOp.get())) { DeclContext *Ctx = dcl->getDeclContext(); if (Ctx && Ctx->isRecord()) { if (dcl->getType()->isReferenceType()) { @@ -14127,22 +14134,6 @@ QualType Sema::CheckAddressOfOperand(ExprResult &OrigOp, SourceLocation OpLoc) { return QualType(); } - // C++11 [expr.unary.op] p4: - // A pointer to member is only formed when an explicit & is used and - // its operand is a qualified-id not enclosed in parentheses. - if (isa<ParenExpr>(OrigOp.get())) { - SourceLocation LeftParenLoc = OrigOp.get()->getBeginLoc(), - RightParenLoc = OrigOp.get()->getEndLoc(); - - Diag(LeftParenLoc, - diag::err_form_ptr_to_member_from_parenthesized_expr) - << SourceRange(OpLoc, RightParenLoc) - << FixItHint::CreateRemoval(LeftParenLoc) - << FixItHint::CreateRemoval(RightParenLoc); - - // Continuing might lead to better error recovery. - } - while (cast<RecordDecl>(Ctx)->isAnonymousStructOrUnion()) Ctx = Ctx->getParent(); |