diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 1299a70c01548..bcabd93304aa2 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1891,6 +1891,9 @@ inline bool ArrayElemPop(InterpState &S, CodePtr OpPC, uint32_t Index) { inline bool ArrayDecay(InterpState &S, CodePtr OpPC) { const Pointer &Ptr = S.Stk.pop(); + if (Ptr.isDummy()) + return false; + if (!Ptr.isUnknownSizeArray()) { S.Stk.push(Ptr.atIndex(0)); return true; diff --git a/clang/test/AST/Interp/arrays.cpp b/clang/test/AST/Interp/arrays.cpp index e14ff34dd7371..dedfa0173908f 100644 --- a/clang/test/AST/Interp/arrays.cpp +++ b/clang/test/AST/Interp/arrays.cpp @@ -598,3 +598,23 @@ namespace NonConstReads { const int y = 0; int yy[y]; } + +namespace SelfComparison { + struct S { + int field; + static int static_field; + int array[4]; + }; + + struct T { + int field; + static int static_field; + int array[4]; + S s; + }; + + int struct_test(S s1, S s2, S *s3, T t) { + return s3->array[t.field] == s3->array[t.field]; // expected-warning {{self-comparison always evaluates to true}} \ + // ref-warning {{self-comparison always evaluates to true}} + }; +} diff --git a/clang/test/SemaCXX/self-comparison.cpp b/clang/test/SemaCXX/self-comparison.cpp index 72127f1102412..c3c875565ff1d 100644 --- a/clang/test/SemaCXX/self-comparison.cpp +++ b/clang/test/SemaCXX/self-comparison.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2a +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++2a -fexperimental-new-constant-interpreter int foo(int x) { return x == x; // expected-warning {{self-comparison always evaluates to true}}