This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG6aac11bad976: [clang][Interp] Evaluate Base when discarding a MemberExpr (authored by tbaeder).
Changed prior to commit: https://reviews.llvm.org/D149828?vs=519395&id=545957#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D149828/new/ https://reviews.llvm.org/D149828 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/literals.cpp Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -876,7 +876,7 @@ } static_assert(ignoredDecls() == 12, ""); -struct A{}; +struct A{ int a; }; constexpr int ignoredExprs() { (void)(1 / 2); A a; @@ -908,6 +908,19 @@ constexpr int Value = Comma(5); static_assert(Value == 8, ""); +/// Ignored MemberExprs need to still evaluate the Base +/// expr. +constexpr A callme(int &i) { + ++i; + return A{}; +} +constexpr int ignoredMemberExpr() { + int i = 0; + callme(i).a; // ref-warning {{result unused}} \ + // expected-warning {{result unused}} + return i; +} +static_assert(ignoredMemberExpr() == 1, ""); #endif namespace PredefinedExprs { Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -562,18 +562,18 @@ template <class Emitter> bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) { - if (DiscardResult) - return true; - // 'Base.Member' const Expr *Base = E->getBase(); - const ValueDecl *Member = E->getMemberDecl(); + + if (DiscardResult) + return this->discard(Base); if (!this->visit(Base)) return false; // Base above gives us a pointer on the stack. // TODO: Implement non-FieldDecl members. + const ValueDecl *Member = E->getMemberDecl(); if (const auto *FD = dyn_cast<FieldDecl>(Member)) { const RecordDecl *RD = FD->getParent(); const Record *R = getRecord(RD);
Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -876,7 +876,7 @@ } static_assert(ignoredDecls() == 12, ""); -struct A{}; +struct A{ int a; }; constexpr int ignoredExprs() { (void)(1 / 2); A a; @@ -908,6 +908,19 @@ constexpr int Value = Comma(5); static_assert(Value == 8, ""); +/// Ignored MemberExprs need to still evaluate the Base +/// expr. +constexpr A callme(int &i) { + ++i; + return A{}; +} +constexpr int ignoredMemberExpr() { + int i = 0; + callme(i).a; // ref-warning {{result unused}} \ + // expected-warning {{result unused}} + return i; +} +static_assert(ignoredMemberExpr() == 1, ""); #endif namespace PredefinedExprs { Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -562,18 +562,18 @@ template <class Emitter> bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) { - if (DiscardResult) - return true; - // 'Base.Member' const Expr *Base = E->getBase(); - const ValueDecl *Member = E->getMemberDecl(); + + if (DiscardResult) + return this->discard(Base); if (!this->visit(Base)) return false; // Base above gives us a pointer on the stack. // TODO: Implement non-FieldDecl members. + const ValueDecl *Member = E->getMemberDecl(); if (const auto *FD = dyn_cast<FieldDecl>(Member)) { const RecordDecl *RD = FD->getParent(); const Record *R = getRecord(RD);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits