Skip to content

Commit 38ffc89

Browse files
committed
[clang][Interp] Fix ignoring expression return values
Randomly noticed this. We need to honor DiscardResult here. Differential Revision: https://reviews.llvm.org/D136013
1 parent 0ccff03 commit 38ffc89

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

Diff for: clang/lib/AST/Interp/ByteCodeExprGen.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,9 @@ bool ByteCodeExprGen<Emitter>::VisitUnaryExprOrTypeTraitExpr(
329329

330330
template <class Emitter>
331331
bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
332+
if (DiscardResult)
333+
return true;
334+
332335
// 'Base.Member'
333336
const Expr *Base = E->getBase();
334337
const ValueDecl *Member = E->getMemberDecl();
@@ -982,7 +985,18 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
982985
// In any case call the function. The return value will end up on the stack and
983986
// if the function has RVO, we already have the pointer on the stack to write
984987
// the result into.
985-
return this->emitCall(Func, E);
988+
if (!this->emitCall(Func, E))
989+
return false;
990+
991+
QualType ReturnType = E->getCallReturnType(Ctx.getASTContext());
992+
if (DiscardResult && !ReturnType->isVoidType()) {
993+
Optional<PrimType> T = classify(ReturnType);
994+
if (T)
995+
return this->emitPop(*T, E);
996+
// TODO: This is a RVO function and we need to ignore the return value.
997+
}
998+
999+
return true;
9861000
} else {
9871001
assert(false && "We don't support non-FunctionDecl callees right now.");
9881002
}
@@ -1032,11 +1046,16 @@ bool ByteCodeExprGen<Emitter>::VisitCXXNullPtrLiteralExpr(
10321046

10331047
template <class Emitter>
10341048
bool ByteCodeExprGen<Emitter>::VisitCXXThisExpr(const CXXThisExpr *E) {
1049+
if (DiscardResult)
1050+
return true;
10351051
return this->emitThis(E);
10361052
}
10371053

10381054
template <class Emitter>
10391055
bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
1056+
if (DiscardResult)
1057+
return true;
1058+
10401059
const Expr *SubExpr = E->getSubExpr();
10411060

10421061
switch (E->getOpcode()) {

Diff for: clang/test/AST/Interp/literals.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,16 @@ namespace bitOr {
279279
static_assert((12 | true) == 13, "");
280280
};
281281

282+
#if __cplusplus >= 201402L
283+
constexpr bool IgnoredUnary() {
284+
bool bo = true;
285+
!bo; // expected-warning {{expression result unused}} \
286+
// ref-warning {{expression result unused}}
287+
return bo;
288+
}
289+
static_assert(IgnoredUnary(), "");
290+
#endif
291+
282292
namespace strings {
283293
constexpr const char *S = "abc";
284294
static_assert(S[0] == 97, "");

Diff for: clang/test/AST/Interp/records.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ static_assert(a2.i == 200, ""); // ref-error {{static assertion failed}} \
204204
// expected-error {{static assertion failed}} \
205205
// expected-note {{evaluates to '12 == 200'}}
206206

207+
208+
struct S {
209+
int a = 0;
210+
constexpr int get5() const { return 5; }
211+
constexpr void fo() const {
212+
this; // expected-warning {{expression result unused}} \
213+
// ref-warning {{expression result unused}}
214+
this->a; // expected-warning {{expression result unused}} \
215+
// ref-warning {{expression result unused}}
216+
get5();
217+
}
218+
219+
constexpr int m() const {
220+
fo();
221+
return 1;
222+
}
223+
};
224+
constexpr S s;
225+
static_assert(s.m() == 1, "");
226+
207227
namespace MI {
208228
class A {
209229
public:

0 commit comments

Comments
 (0)