Skip to content

Commit 1d8eb43

Browse files
authored
[clang][bytecode] Diagnose member calls on inactive union fields (#129709)
Unless the function is a constructor, which is allowed to do this since it will activate the member.
1 parent 9ad5156 commit 1d8eb43

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,9 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
13411341
} else {
13421342
if (!CheckInvoke(S, OpPC, ThisPtr))
13431343
return cleanup();
1344+
if (!Func->isConstructor() &&
1345+
!CheckActive(S, OpPC, ThisPtr, AK_MemberCall))
1346+
return false;
13441347
}
13451348

13461349
if (Func->isConstructor() && !checkConstructor(S, OpPC, Func, ThisPtr))

clang/test/AST/ByteCode/unions.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,4 +504,22 @@ namespace AnonymousUnion {
504504
static_assert(return_init_all().a.p == 7); // both-error {{}} \
505505
// both-note {{read of member 'p' of union with no active member}}
506506
}
507+
508+
namespace MemberCalls {
509+
struct S {
510+
constexpr bool foo() const { return true; }
511+
};
512+
513+
constexpr bool foo() { // both-error {{never produces a constant expression}}
514+
union {
515+
int a;
516+
S s;
517+
} u;
518+
519+
u.a = 10;
520+
return u.s.foo(); // both-note 2{{member call on member 's' of union with active member 'a'}}
521+
}
522+
static_assert(foo()); // both-error {{not an integral constant expression}} \
523+
// both-note {{in call to}}
524+
}
507525
#endif

0 commit comments

Comments
 (0)