aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorcor3ntin <corentinjabot@gmail.com>2024-07-22 15:57:22 +0200
committerGitHub <noreply@github.com>2024-07-22 15:57:22 +0200
commit3c459cfcaebdaf7cabac33a0e18bf6588cef4cdb (patch)
tree7067c8550332cfac4ee132d769ad7a53368eb7ac /clang/lib
parentbc4c3bf1b75fec183e2616d6688aa155d6aada74 (diff)
downloadllvm-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.cpp25
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();