Skip to content

Commit 181e4c6

Browse files
committed
[clang][Interp] Check for non-primitive types in unary operators
For invalid cases (non-vector/complex/...), this should only happen in error cases such as the attached test case.
1 parent 9d88990 commit 181e4c6

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

clang/lib/AST/Interp/Compiler.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4706,6 +4706,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
47064706
case UO_PostInc: { // x++
47074707
if (!Ctx.getLangOpts().CPlusPlus14)
47084708
return this->emitInvalid(E);
4709+
if (!T)
4710+
return this->emitError(E);
47094711

47104712
if (!this->visit(SubExpr))
47114713
return false;
@@ -4727,6 +4729,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
47274729
case UO_PostDec: { // x--
47284730
if (!Ctx.getLangOpts().CPlusPlus14)
47294731
return this->emitInvalid(E);
4732+
if (!T)
4733+
return this->emitError(E);
47304734

47314735
if (!this->visit(SubExpr))
47324736
return false;
@@ -4748,6 +4752,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
47484752
case UO_PreInc: { // ++x
47494753
if (!Ctx.getLangOpts().CPlusPlus14)
47504754
return this->emitInvalid(E);
4755+
if (!T)
4756+
return this->emitError(E);
47514757

47524758
if (!this->visit(SubExpr))
47534759
return false;
@@ -4795,6 +4801,8 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
47954801
case UO_PreDec: { // --x
47964802
if (!Ctx.getLangOpts().CPlusPlus14)
47974803
return this->emitInvalid(E);
4804+
if (!T)
4805+
return this->emitError(E);
47984806

47994807
if (!this->visit(SubExpr))
48004808
return false;
@@ -4840,6 +4848,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
48404848
return E->isGLValue() || this->emitLoadPop(*T, E);
48414849
}
48424850
case UO_LNot: // !x
4851+
if (!T)
4852+
return this->emitError(E);
4853+
48434854
if (DiscardResult)
48444855
return this->discard(SubExpr);
48454856

@@ -4853,10 +4864,16 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
48534864
return this->emitCast(PT_Bool, ET, E);
48544865
return true;
48554866
case UO_Minus: // -x
4867+
if (!T)
4868+
return this->emitError(E);
4869+
48564870
if (!this->visit(SubExpr))
48574871
return false;
48584872
return DiscardResult ? this->emitPop(*T, E) : this->emitNeg(*T, E);
48594873
case UO_Plus: // +x
4874+
if (!T)
4875+
return this->emitError(E);
4876+
48604877
if (!this->visit(SubExpr)) // noop
48614878
return false;
48624879
return DiscardResult ? this->emitPop(*T, E) : true;
@@ -4873,6 +4890,9 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
48734890
return this->discard(SubExpr);
48744891
return this->visit(SubExpr);
48754892
case UO_Not: // ~x
4893+
if (!T)
4894+
return this->emitError(E);
4895+
48764896
if (!this->visit(SubExpr))
48774897
return false;
48784898
return DiscardResult ? this->emitPop(*T, E) : this->emitComp(*T, E);

clang/test/AST/Interp/literals.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,3 +1290,13 @@ namespace NTTP {
12901290
return size(Chars);
12911291
}
12921292
}
1293+
1294+
#if __cplusplus >= 201402L
1295+
namespace UnaryOpError {
1296+
constexpr int foo() {
1297+
int f = 0;
1298+
++g; // both-error {{use of undeclared identifier 'g'}}
1299+
return f;
1300+
}
1301+
}
1302+
#endif

0 commit comments

Comments
 (0)