llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Michael Flanders (Flandini) <details> <summary>Changes</summary> Related to #<!-- -->127702. I figured that if I change list initialization like mentioned in #<!-- -->127702, then I would want these tests anyways, so I am adding them first. This adds more test coverage of C++ list initialization and aggregate initialization. I tried to make sure there is at least one basic test case for each paragraph/note of the list initialization and aggregate initialization sections, C++11 through C++20. I grouped all of the C++ list-initialization-specifics tests into this new file `list-initialization.cpp`. `list-initialization.cpp` is separated into a 'common to all C++ standard editions' section and a 'C++17 and above section'. I figure this is fine since it still allows coverage for all of the list initialization and aggregate initialization sections, C++11 through C++20 at least. This does not include the tests from #<!-- -->127702. If this is approved, I will merge the tests from this and #<!-- -->127702 into whichever gets merged last. This includes a test case for a related issue #<!-- -->54910. There are `FIXME`'s for each test case that should have different behavior than current main branch. I checked all of these and checked them against normal compilation. Happy to add more test cases if anyone can think of any more fun tests like #<!-- -->54910. --- Patch is 39.60 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129182.diff 3 Files Affected: - (modified) clang/test/Analysis/initialization.cpp (-154) - (modified) clang/test/Analysis/initializer.cpp (-79) - (added) clang/test/Analysis/list-initialization.cpp (+910) ``````````diff diff --git a/clang/test/Analysis/initialization.cpp b/clang/test/Analysis/initialization.cpp index e624ef5bae9e9..164011f19c5c3 100644 --- a/clang/test/Analysis/initialization.cpp +++ b/clang/test/Analysis/initialization.cpp @@ -4,105 +4,6 @@ template <typename T> void clang_analyzer_dump(T x); void clang_analyzer_eval(int); -struct S { - int a = 3; -}; -S const sarr[2] = {}; -void definit() { - int i = 1; - // FIXME: Should recognize that it is 3. - clang_analyzer_eval(sarr[i].a); // expected-warning{{UNKNOWN}} -} - -int const glob_arr1[3] = {}; -void glob_array_index1() { - clang_analyzer_eval(glob_arr1[0] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr1[1] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr1[2] == 0); // expected-warning{{TRUE}} -} - -void glob_invalid_index1() { - const int *ptr = glob_arr1; - int idx = -42; - auto x = ptr[idx]; // expected-warning{{garbage or undefined}} -} - -void glob_symbolic_index1(int idx) { - clang_analyzer_dump(glob_arr1[idx]); // expected-warning{{Unknown}} -} - -int const glob_arr2[4] = {1, 2}; -void glob_ptr_index1() { - int const *ptr = glob_arr2; - clang_analyzer_eval(ptr[0] == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[1] == 2); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[2] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[3] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[4] == 0); // expected-warning{{UNDEFINED}} -} - -void glob_invalid_index2() { - const int *ptr = glob_arr2; - int idx = 42; - auto x = ptr[idx]; // expected-warning{{garbage or undefined}} -} - -const float glob_arr3[] = { - 0.0000, 0.0235, 0.0470, 0.0706, 0.0941, 0.1176}; -float no_warn_garbage_value() { - return glob_arr3[0]; // no-warning (garbage or undefined) -} - -int const glob_arr4[4][2] = {}; -void glob_array_index2() { - clang_analyzer_eval(glob_arr4[0][0] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr4[1][0] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr4[1][1] == 0); // expected-warning{{TRUE}} -} - -void glob_invalid_index3() { - int idx = -42; - auto x = glob_arr4[1][idx]; // expected-warning{{garbage or undefined}} -} - -void glob_invalid_index4() { - const int *ptr = glob_arr4[1]; - int idx = -42; - auto x = ptr[idx]; // expected-warning{{garbage or undefined}} -} - -int const glob_arr5[4][2] = {{1}, 3, 4, 5}; -void glob_array_index3() { - clang_analyzer_eval(glob_arr5[0][0] == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[0][1] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[1][0] == 3); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[1][1] == 4); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[2][0] == 5); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[2][1] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[3][0] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr5[3][1] == 0); // expected-warning{{TRUE}} -} - -void glob_ptr_index2() { - int const *ptr = glob_arr5[1]; - clang_analyzer_eval(ptr[0] == 3); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[1] == 4); // expected-warning{{TRUE}} - clang_analyzer_eval(ptr[2] == 5); // expected-warning{{UNDEFINED}} - clang_analyzer_eval(ptr[3] == 0); // expected-warning{{UNDEFINED}} - clang_analyzer_eval(ptr[4] == 0); // expected-warning{{UNDEFINED}} -} - -void glob_invalid_index5() { - int idx = -42; - auto x = glob_arr5[1][idx]; // expected-warning{{garbage or undefined}} -} - -void glob_invalid_index6() { - int const *ptr = &glob_arr5[1][0]; - int idx = 42; - auto x = ptr[idx]; // expected-warning{{garbage or undefined}} -} - extern const int glob_arr_no_init[10]; void glob_array_index4() { clang_analyzer_eval(glob_arr_no_init[2]); // expected-warning{{UNKNOWN}} @@ -147,26 +48,6 @@ void glob_invalid_index8() { auto x = ptr[idx]; // expected-warning{{garbage or undefined}} } -char const glob_arr7[5] = {"123"}; -void glob_array_index6() { - clang_analyzer_eval(glob_arr7[0] == '1'); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr7[1] == '2'); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr7[2] == '3'); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr7[3] == '\0'); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr7[4] == '\0'); // expected-warning{{TRUE}} -} - -void glob_invalid_index9() { - int idx = -42; - auto x = glob_arr7[idx]; // expected-warning{{garbage or undefined}} -} - -void glob_invalid_index10() { - const char *ptr = glob_arr7; - int idx = 42; - auto x = ptr[idx]; // expected-warning{{garbage or undefined}} -} - char const *const glob_ptr8 = "123"; void glob_ptr_index4() { clang_analyzer_eval(glob_ptr8[0] == '1'); // expected-warning{{TRUE}} @@ -221,38 +102,3 @@ void glob_ptr_index8() { clang_analyzer_eval(glob_ptr12[2] == 'c'); // expected-warning{{TRUE}} clang_analyzer_eval(glob_ptr12[3] == '\0'); // expected-warning{{TRUE}} } - -typedef int Int; -typedef Int const CInt; -typedef CInt Arr[2]; -typedef Arr Arr2[4]; -Arr2 glob_arr8 = {{1}, 3, 4, 5}; // const int[4][2] -void glob_array_typedef1() { - clang_analyzer_eval(glob_arr8[0][0] == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[0][1] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[1][0] == 3); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[1][1] == 4); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[2][0] == 5); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[2][1] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[3][0] == 0); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr8[3][1] == 0); // expected-warning{{TRUE}} -} - -const int glob_arr9[2][4] = {{(1), 2, ((3)), 4}, 5, 6, (((7)))}; -void glob_array_parentheses1() { - clang_analyzer_eval(glob_arr9[0][0] == 1); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[0][1] == 2); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[0][2] == 3); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[0][3] == 4); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[1][0] == 5); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[1][1] == 6); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[1][2] == 7); // expected-warning{{TRUE}} - clang_analyzer_eval(glob_arr9[1][3] == 0); // expected-warning{{TRUE}} -} - -enum class E {}; -const E glob[] = {{}}; -void initlistWithinInitlist() { - // no-crash - clang_analyzer_dump(glob[0]); // expected-warning-re {{reg_${{[0-9]+}}<enum E Element{glob,0 S64b,enum E}>}} -} diff --git a/clang/test/Analysis/initializer.cpp b/clang/test/Analysis/initializer.cpp index f50afff25d245..2dfb878fa057e 100644 --- a/clang/test/Analysis/initializer.cpp +++ b/clang/test/Analysis/initializer.cpp @@ -197,85 +197,6 @@ struct C { }; } -namespace CXX_initializer_lists { -struct C { - C(std::initializer_list<int *> list); -}; -void testPointerEscapeIntoLists() { - C empty{}; // no-crash - - // Do not warn that 'x' leaks. It might have been deleted by - // the destructor of 'c'. - int *x = new int; - C c{x}; // no-warning -} - -void testPassListsWithExplicitConstructors() { - (void)(std::initializer_list<int>){12}; // no-crash -} -} - -namespace CXX17_aggregate_construction { -struct A { - A(); -}; - -struct B: public A { -}; - -struct C: public B { -}; - -struct D: public virtual A { -}; - -// In C++17, classes B and C are aggregates, so they will be constructed -// without actually calling their trivial constructor. Used to crash. -void foo() { - B b = {}; // no-crash - const B &bl = {}; // no-crash - B &&br = {}; // no-crash - - C c = {}; // no-crash - const C &cl = {}; // no-crash - C &&cr = {}; // no-crash - - D d = {}; // no-crash - -#if __cplusplus >= 201703L - C cd = {{}}; // no-crash - const C &cdl = {{}}; // no-crash - C &&cdr = {{}}; // no-crash - - const B &bll = {{}}; // no-crash - const B &bcl = C({{}}); // no-crash - B &&bcr = C({{}}); // no-crash -#endif -} -} // namespace CXX17_aggregate_construction - -namespace CXX17_transparent_init_list_exprs { -class A {}; - -class B: private A {}; - -B boo(); -void foo1() { - B b { boo() }; // no-crash -} - -class C: virtual public A {}; - -C coo(); -void foo2() { - C c { coo() }; // no-crash -} - -B foo_recursive() { - B b { foo_recursive() }; -} -} // namespace CXX17_transparent_init_list_exprs - namespace skip_vbase_initializer_side_effects { int glob; struct S { diff --git a/clang/test/Analysis/list-initialization.cpp b/clang/test/Analysis/list-initialization.cpp new file mode 100644 index 0000000000000..2c68b437411ec --- /dev/null +++ b/clang/test/Analysis/list-initialization.cpp @@ -0,0 +1,910 @@ +// RUN: %clang_analyze_cc1 -verify %s\ +// RUN: -analyzer-checker=core,unix.Malloc\ +// RUN: -analyzer-checker=debug.ExprInspection -std=c++11 +// RUN: %clang_analyze_cc1 -verify %s\ +// RUN: -analyzer-checker=core,unix.Malloc\ +// RUN: -analyzer-checker=debug.ExprInspection -std=c++17 + +template <typename T> +void clang_analyzer_dump(T x); +void clang_analyzer_eval(bool); + +#include "Inputs/system-header-simulator-cxx.h" + +// in C++14 and below, class types with bases are not aggregates, but they +// are in C++17 and above +#if __cplusplus >= 201703L +namespace CXX17_base_class_aggregates { +struct A { + A(); +}; + +struct B: public A { +}; + +struct C: public B { +}; + +struct D: public virtual A { +}; + +// In C++17, classes B and C are aggregates, so they will be constructed +// without actually calling their trivial constructor. Used to crash. +void foo() { + B b = {}; // no-crash + const B &bl = {}; // no-crash + B &&br = {}; // no-crash + + C c = {}; // no-crash + const C &cl = {}; // no-crash + C &&cr = {}; // no-crash + + D d = {}; // no-crash + + + C cd = {{}}; // no-crash + const C &cdl = {{}}; // no-crash + C &&cdr = {{}}; // no-crash + + const B &bll = {{}}; // no-crash + const B &bcl = C({{}}); // no-crash + B &&bcr = C({{}}); // no-crash +} + +struct S1 { + int one; + int two; +}; +struct S2 { + int three; +}; +struct T : public S1, public S2 { + int four; + int five; +}; +void fields_init_in_order() { + T direct{1,2,3,4}; + clang_analyzer_eval(direct.one == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(direct.two == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(direct.three == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(direct.four == 4); // expected-warning{{TRUE}} + clang_analyzer_eval(direct.five == 0); // expected-warning{{TRUE}} + + T copy = {1,2,3,4}; + clang_analyzer_eval(copy.one == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(copy.two == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(copy.three == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(copy.four == 4); // expected-warning{{TRUE}} + clang_analyzer_eval(copy.five == 0); // expected-warning{{TRUE}} + + T *ptr = new T{1,2,3,4}; + clang_analyzer_eval(ptr->one == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(ptr->two == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(ptr->three == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(ptr->four == 4); // expected-warning{{TRUE}} + clang_analyzer_eval(ptr->five == 0); // expected-warning{{TRUE}} + delete ptr; + + T slot; + T *place = new (&slot) T{1,2,3,4}; + clang_analyzer_eval(place->one == 1); // expected-warning{{TRUE}} + clang_analyzer_eval(place->two == 2); // expected-warning{{TRUE}} + clang_analyzer_eval(place->three == 3); // expected-warning{{TRUE}} + clang_analyzer_eval(place->four == 4); // expected-warning{{TRUE}} + clang_analyzer_eval(place->five == 0); // expected-warning{{TRUE}} +} + +struct DefaultOne { + int one = 1; +}; +struct DefaultTwo { + int two = 2; +}; +struct Deriver : public DefaultOne, public DefaultTwo { +}; +void empty_lists_bases() { + Deriver direct{{}, {}}; + Deriver copy = {{}, {}}; + Deriver *ptr = new Deriver{{},{}}; + + Deriver slot; + Deriver *place = new (&slot) Deriver{{},{}}; + + clang_analyzer_eval(1 == direct.one); // expected-warning{{TRUE}} + clang_analyzer_eval(2 == direct.two); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == copy.one); // expected-warning{{TRUE}} + clang_analyzer_eval(2 == copy.two); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == ptr->one); // expected-warning{{TRUE}} + clang_analyzer_eval(2 == ptr->two); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == place->one); // expected-warning{{TRUE}} + clang_analyzer_eval(2 == place->two); // expected-warning{{TRUE}} + + delete ptr; +} +} // namespace CXX17_base_class_aggregates + +// C++14 and below don't allow list initialization of enums, C++17 and above do +namespace CXX17_enum_list_init { + +enum class E {}; +const E glob[] = {{}}; +void initlistWithinInitlist() { + // no-crash + clang_analyzer_dump(glob[0]); // expected-warning-re {{reg_${{[0-9]+}}<enum CXX17_enum_list_init::E Element{glob,0 S64b,enum CXX17_enum_list_init::E}>}} +} + +enum UnderlyingStorage : int { +}; +void init_value() { + // No copy list initialization, only direct list init of enum with underlying type + // is allowed + UnderlyingStorage direct{1}; + UnderlyingStorage *ptr = new UnderlyingStorage{1}; + UnderlyingStorage slot; + UnderlyingStorage *place = new (&slot) UnderlyingStorage{1}; + clang_analyzer_eval(1 == direct); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == *ptr); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == *place); // expected-warning{{TRUE}} +} +void empty_list_init() { + UnderlyingStorage direct{}; + UnderlyingStorage *ptr = new UnderlyingStorage{}; + UnderlyingStorage slot; + UnderlyingStorage *place = new (&slot) UnderlyingStorage{}; + clang_analyzer_eval(0 == direct); // expected-warning{{TRUE}} + clang_analyzer_eval(0 == *ptr); // expected-warning{{TRUE}} + clang_analyzer_eval(0 == *place); // expected-warning{{TRUE}} +} +} // namespace CXX17_enum_list_init + +namespace CXX17_anonymous_union_aggregate_member { +struct S { + int x; + union { + int a; + int b; + }; + int y; +}; +void no_designated_clause() { + S direct{1,2}; + clang_analyzer_eval(1 == direct.x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(2 == direct.y); // expected-warning{{FALSE}} + // FIXME: should be undefined + clang_analyzer_eval(direct.a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(direct.b); // expected-warning{{UNKNOWN}} + + S copy = {3,4}; + clang_analyzer_eval(3 == copy.x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(4 == copy.y); // expected-warning{{FALSE}} + // FIXME: should be undefined + clang_analyzer_eval(copy.a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(copy.b); // expected-warning{{UNKNOWN}} + + S *ptr = new S{5, 6}; + clang_analyzer_eval(5 == ptr->x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(6 == ptr->y); // expected-warning{{FALSE}} + // FIXME: should be undefined + clang_analyzer_eval(ptr->a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(ptr->b); // expected-warning{{UNKNOWN}} + + S slot; + S *place = new (&slot) S{7,8}; + clang_analyzer_eval(7 == place->x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(8 == place->y); // expected-warning{{FALSE}} + // FIXME: should be undefined + clang_analyzer_eval(place->a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(place->b); // expected-warning{{UNKNOWN}} + + delete ptr; +} +void designated_clause() { + S direct{.a = 14}; + clang_analyzer_eval(0 == direct.x); // expected-warning{{TRUE}} + clang_analyzer_eval(0 == direct.y); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(14 == direct.a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(direct.b); // expected-warning{{UNKNOWN}} + + S copy = {.a = 14}; + clang_analyzer_eval(0 == copy.x); // expected-warning{{TRUE}} + clang_analyzer_eval(0 == copy.y); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(14 == copy.a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(copy.b); // expected-warning{{UNKNOWN}} + + S *ptr = new S{.b = 14}; + clang_analyzer_eval(0 == ptr->x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(0 == ptr->y); // expected-warning{{TRUE}} + // FIXME: should be undefined + clang_analyzer_eval(ptr->a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(14 == ptr->b); // expected-warning{{UNKNOWN}} + + S slot; + S *place = new (&slot) S{.b = 14}; + clang_analyzer_eval(0 == place->x); // expected-warning{{TRUE}} + // FIXME: should be TRUE + clang_analyzer_eval(0 == place->y); // expected-warning{{TRUE}} + // FIXME: should be undefined + clang_analyzer_eval(place->a); // expected-warning{{UNKNOWN}} + // FIXME: should be undefined + clang_analyzer_eval(14 == place->b); // expected-warning{{UNKNOWN}} + + delete ptr; +} +} // namespace CXX17_anonymous_union_aggregate_member + +// These next are C++14 and up, but just test under C++17 +namespace CXX14_default_member_initializers { +struct DMIPreviousField { + int a; + int b[2]; + int c = b[a]; +}; +void dmi_properly_sequenced() { + DMIPreviousField direct{0, {14, 1}}; + clang_analyzer_eval(0 == direct.a); // expected-warning{{TRUE}} + clang_analyzer_eval(14 == direct.b[0]); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == direct.b[1]); // expected-warning{{TRUE}} + // FIXME: should be true + clang_analyzer_eval(14 == direct.c); // expected-warning{{UNKNOWN}} + + DMIPreviousField copy = {0, {14, 1}}; + clang_analyzer_eval(0 == copy.a); // expected-warning{{TRUE}} + clang_analyzer_eval(14 == copy.b[0]); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == copy.b[1]); // expected-warning{{TRUE}} + // FIXME: should be true + clang_analyzer_eval(14 == copy.c); // expected-warning{{UNKNOWN}} + + DMIPreviousField *ptr = new DMIPreviousField{0, {14, 1}}; + clang_analyzer_eval(0 == ptr->a); // expected-warning{{TRUE}} + clang_analyzer_eval(14 == ptr->b[0]); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == ptr->b[1]); // expected-warning{{TRUE}} + // FIXME: should be true + clang_analyzer_eval(14 == ptr->c); // expected-warning{{UNKNOWN}} + delete ptr; + + DMIPreviousField slot{0, {14, 1}}; + auto place = new (&slot) DMIPreviousField{0, {14, 1}}; + clang_analyzer_eval(0 == place->a); // expected-warning{{TRUE}} + clang_analyzer_eval(14 == place->b[0]); // expected-warning{{TRUE}} + clang_analyzer_eval(1 == place->b[1]); // expected-warning{{TRUE}} + // FIXME: should be true + clang_analyzer_eval(14 == place->c); // expected-warning{{UNKNOWN}} +} + +union UDMI { + int x; + int y = 1; +}; +void union_empty_init_list_default_member_initializer() { + UDMI direct{}; + // FIXME: should be TRUE and undefined + clang_analyzer_eval(1 == direct.y); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(direct.x); // expected-warning{{UNKNOWN}} + + UDMI copy = {}; + // FIXME: should be TRUE and undefined + clang_analyzer_eval(1 == copy.y); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(copy.x); // expected-warning{{UNKNOWN}} + + auto ptr = new UDMI{}; + // FIXME: should be TRUE and undefined + clang_analyzer_eval(1 == ptr->y); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(ptr->x); // expected-warning{{UNKNOWN}} + + UDMI slot; + auto place = new (&slot) UDMI{}; + // FIXME: should be TRUE and undefined + clang_analyzer_eval(1 == place->y); // expected-warning{{UNKNOWN}} + clang_analyzer_eval(place->x); // expected-warning{{UNKNOWN}} +} + +struct ArrElt { + int a = 3; +}; +ArrElt const sarr[2] = {}; +void array_list_init_aggregates_default_member_initializers() { + int i = 1; + // Should this not cause a split? + clang_analyzer_eval(3 == sarr[i].a); // expected-warning{{TRUE}} expected-warning{{FALSE}} +} +} // CXX14_default_member_initializers + +namespace CXX14_same_or_derived_class { +struct T { + int x; +}; +struct ... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/129182 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits