================ @@ -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()) ---------------- MitalAshok wrote:
(Tested locally on v19.41.33923) MSVC does not seem to implement CWG2813 so this: ```c++ struct S { S(const S&) = delete; S() = default; int getX(this S) { return 42; } __declspec(property(get = getX)) int x; }; int main() { return S().x; } ``` ... doesn't compile (attempts to call `S::S(const S&)` on the temporary to construct the explicit object argument). I assume MSVC will eventually allow this, so we should wait to materialize the temporary here? Especially since https://learn.microsoft.com/en-gb/cpp/cpp/property-cpp?view=msvc-170 describes properties directly as a transformation from data member access -> member function call. I'll get this changed https://github.com/llvm/llvm-project/pull/95112 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits