diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -329,6 +329,9 @@ template bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) { + if (DiscardResult) + return true; + // 'Base.Member' const Expr *Base = E->getBase(); const ValueDecl *Member = E->getMemberDecl(); @@ -982,7 +985,18 @@ // 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 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 @@ template bool ByteCodeExprGen::VisitCXXThisExpr(const CXXThisExpr *E) { + if (DiscardResult) + return true; return this->emitThis(E); } template bool ByteCodeExprGen::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 --- a/clang/test/AST/Interp/literals.cpp +++ b/clang/test/AST/Interp/literals.cpp @@ -279,6 +279,16 @@ 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 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -204,6 +204,26 @@ // 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: