[clang] [clang-tools-extra] [Clang] Implement CWG2813: Class member access with prvalues (PR #95112)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 13 13:35:58 PDT 2024
================
@@ -1140,26 +1131,68 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
BaseExpr = BuildCXXThisExpr(Loc, BaseExprType, /*IsImplicit=*/true);
}
+ // C++17 [expr.ref]p2, per CWG2813:
+ // For the first option (dot), if the id-expression names a static member or
+ // an enumerator, the first expression is a discarded-value expression; if
+ // the id-expression names a non-static data member, the first expression
+ // shall be a glvalue.
+ auto MakeDiscardedValue = [&BaseExpr, IsArrow, this] {
+ assert(getLangOpts().CPlusPlus &&
+ "Static member / member enumerator outside of C++");
+ if (IsArrow)
+ return false;
+ ExprResult Converted = IgnoredValueConversions(BaseExpr);
+ if (Converted.isInvalid())
+ return true;
+ BaseExpr = Converted.get();
+ DiagnoseUnusedExprResult(BaseExpr,
+ diag::warn_discarded_class_member_access);
+ return false;
+ };
+ auto MakeGLValue = [&BaseExpr, IsArrow, this] {
+ if (IsArrow || !BaseExpr->isPRValue())
+ return false;
+ ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+ if (Converted.isInvalid())
+ return true;
+ BaseExpr = Converted.get();
+ return false;
+ };
+
// Check the use of this member.
if (DiagnoseUseOfDecl(MemberDecl, MemberLoc))
return ExprError();
- if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl))
+ if (FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl)) {
+ if (MakeGLValue())
+ return ExprError();
return BuildFieldReferenceExpr(BaseExpr, IsArrow, OpLoc, SS, FD, FoundDecl,
MemberNameInfo);
+ }
- if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl))
+ if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl)) {
+ // Properties treated as non-static data members for the purpose of
+ // temporary materialization
+ if (MakeGLValue())
----------------
Sirraide wrote:
I’m not sure this is correct. Consider e.g. https://godbolt.org/z/exK1cbez4 (compiled w/ `-fdeclspec`):
```c++
struct S {
static int getX() { return 42; }
__declspec(property(get = getX))
int x;
};
int main() {
return S().x;
}
```
I’d expect this defect report to also apply to this (if properties were a standard C++ feature, that is) seeing as it is just sugar for a call to a static member function.
(I’d love to see what MSVC does w/ this, but unfortunately, MSVC is currently down on godbolt...)
https://github.com/llvm/llvm-project/pull/95112
More information about the cfe-commits
mailing list