Author: Timm Bäder Date: 2022-10-28T16:45:38+02:00 New Revision: 38ffc89c87ac3b0b1c2173728fba2258dead9ae0
URL: https://github.com/llvm/llvm-project/commit/38ffc89c87ac3b0b1c2173728fba2258dead9ae0 DIFF: https://github.com/llvm/llvm-project/commit/38ffc89c87ac3b0b1c2173728fba2258dead9ae0.diff LOG: [clang][Interp] Fix ignoring expression return values Randomly noticed this. We need to honor DiscardResult here. Differential Revision: https://reviews.llvm.org/D136013 Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/literals.cpp clang/test/AST/Interp/records.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index cbbd6f33e685..20e5d2911a1f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -329,6 +329,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr( 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(); @@ -982,7 +985,18 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) { // In any case call the function. The return value will end up on the stack and // if the function has RVO, we already have the pointer on the stack to write // the result into. - return this->emitCall(Func, E); + if (!this->emitCall(Func, E)) + return false; + + QualType ReturnType = E->getCallReturnType(Ctx.getASTContext()); + if (DiscardResult && !ReturnType->isVoidType()) { + Optional<PrimType> T = classify(ReturnType); + if (T) + return this->emitPop(*T, E); + // TODO: This is a RVO function and we need to ignore the return value. + } + + return true; } else { assert(false && "We don't support non-FunctionDecl callees right now."); } @@ -1032,11 +1046,16 @@ bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr( template <class Emitter> bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) { + if (DiscardResult) + return true; return this->emitThis(E); } template <class Emitter> bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) { + if (DiscardResult) + return true; + const Expr *SubExpr = E->getSubExpr(); switch (E->getOpcode()) { diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp index ca76be9b0bf9..3eba13cff188 100644 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -279,6 +279,16 @@ namespace bitOr { static_assert((12 | true) == 13, ""); }; +#if __cplusplus >= 201402L +constexpr bool IgnoredUnary() { + bool bo = true; + !bo; // expected-warning {{expression result unused}} \ + // ref-warning {{expression result unused}} + return bo; +} +static_assert(IgnoredUnary(), ""); +#endif + namespace strings { constexpr const char *S = "abc"; static_assert(S[0] == 97, ""); diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 18caf5d8f4f0..d8ac72319c0a 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -204,6 +204,26 @@ static_assert(a2.i == 200, ""); // ref-error {{static assertion failed}} \ // expected-error {{static assertion failed}} \ // expected-note {{evaluates to '12 == 200'}} + +struct S { + int a = 0; + constexpr int get5() const { return 5; } + constexpr void fo() const { + this; // expected-warning {{expression result unused}} \ + // ref-warning {{expression result unused}} + this->a; // expected-warning {{expression result unused}} \ + // ref-warning {{expression result unused}} + get5(); + } + + constexpr int m() const { + fo(); + return 1; + } +}; +constexpr S s; +static_assert(s.m() == 1, ""); + namespace MI { class A { public: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits