[clang] [analyzer] Do list initialization for CXXNewExpr with initializer list arg (PR #127702)
Michael Flanders via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 20 07:36:48 PST 2025
================
@@ -254,6 +254,200 @@ void foo() {
}
} // namespace CXX17_aggregate_construction
+namespace newexpr_init_list_initialization {
+struct S {
+ int foo;
+ int bar;
+};
+void none_designated() {
+ S *s = new S{13,1};
+ clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(1 == s->bar); // expected-warning{{TRUE}}
+ delete s;
+}
+void none_designated_swapped() {
+ S *s = new S{1,13};
+ clang_analyzer_eval(1 == s->foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(13 == s->bar); // expected-warning{{TRUE}}
+ delete s;
+}
+void one_designated_one_not() {
+ S *s = new S{ 1, .bar = 13 };
+ clang_analyzer_eval(1 == s->foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(13 == s->bar); // expected-warning{{TRUE}}
+ delete s;
+}
+void all_designated() {
+ S *s = new S{
+ .foo = 13,
+ .bar = 1,
+ };
+ clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(1 == s->bar); // expected-warning{{TRUE}}
+ delete s;
+}
+void non_designated_array_of_aggr_struct() {
+ S *s = new S[2] { {1, 2}, {3, 4} };
+ clang_analyzer_eval(1 == s[0].foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(2 == s[0].bar); // expected-warning{{TRUE}}
+ clang_analyzer_eval(3 == s[1].foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(4 == s[1].bar); // expected-warning{{TRUE}}
+ delete[] s;
+}
+
+struct WithGaps {
+ int foo;
+ int bar;
+ int baz;
+};
+void out_of_order_designated_initializers_with_gaps() {
+ WithGaps *s = new WithGaps{
+ .foo = 13,
+ .baz = 1,
+ };
+ clang_analyzer_eval(13 == s->foo); // expected-warning{{TRUE}}
+ clang_analyzer_eval(0 == s->bar); // expected-warning{{TRUE}}
+ clang_analyzer_eval(1 == s->baz); // expected-warning{{TRUE}}
+ delete s;
+}
+
+// https://eel.is/c++draft/dcl.init.aggr#note-6:
+// Static data members, non-static data members of anonymous
+// union members, and unnamed bit-fields are not considered
+// elements of the aggregate.
+struct NonConsideredFields {
+ int i;
+ static int s;
+ int j;
+ int :17;
+ int k;
+};
+void considered_fields_initd() {
+ auto S = new NonConsideredFields { 1, 2, 3 };
+ clang_analyzer_eval(1 == S->i); // expected-warning{{TRUE}}
+ clang_analyzer_eval(2 == S->j); // expected-warning{{TRUE}}
+ clang_analyzer_eval(3 == S->k); // expected-warning{{TRUE}}
+ delete S;
+}
+
+enum Enum : int {
+};
+// FIXME: uncomment when CSA supports list init of enums
+void list_init_enum() {
+ // Enum *E = new Enum{53};
+ // clang_analyzer_eval(53 == *E); // should be TRUE
+ // delete E;
+}
----------------
Flandini wrote:
When I uncomment those lines, the test fails and then all the other tests after it fail. Looks like `-std=c++11` causes this test to fail with:
```
clang++: warning: argument unused during compilation: '-S' [-Wunused-command-line-argument]
<source>:4:22: error: cannot initialize a new value of type 'Enum' with an rvalue of type 'int'
4 | Enum *E = new Enum{53};
| ^~
1 error generated.
Compiler returned: 1
```
https://compiler-explorer.com/z/hj7qdehs3
I wrongly assumed it just wasn't supported then, but I guess this is different in C++11 vs later editions. Seems like it is clang/Sema warning on this https://godbolt.org/z/d7xEec8Ec.
So this test case would need to be executed only for some version after C++11 then. I don't currently know which version makes this possible, but I'll look.
https://github.com/llvm/llvm-project/pull/127702
More information about the cfe-commits
mailing list