-
Notifications
You must be signed in to change notification settings - Fork 15.9k
Reapply "[analyzer] Handle [[assume(cond)]] as __builtin_assume(cond)" #129234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
67d6420
2e7c4e7
bed6511
f493f9b
54f3aea
e1625b8
d3790ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| // RUN: %clang_analyze_cc1 -std=c++23 -triple x86_64-pc-linux-gnu \ | ||
| // RUN: -analyzer-checker=core,debug.ExprInspection -verify %s | ||
|
|
||
| template <typename T> void clang_analyzer_dump(T); | ||
| template <typename T> void clang_analyzer_value(T); | ||
|
|
||
| int ternary_in_builtin_assume(int a, int b) { | ||
| __builtin_assume(a > 10 ? b == 4 : b == 10); | ||
|
|
||
| clang_analyzer_value(a); | ||
| // expected-warning@-1 {{[-2147483648, 10]}} | ||
| // expected-warning@-2 {{[11, 2147483647]}} | ||
|
|
||
| clang_analyzer_dump(b); // expected-warning{{4}} expected-warning{{10}} | ||
|
|
||
| if (a > 20) { | ||
| clang_analyzer_dump(b + 100); // expected-warning {{104}} | ||
| return 2; | ||
| } | ||
| if (a > 10) { | ||
| clang_analyzer_dump(b + 200); // expected-warning {{204}} | ||
| return 1; | ||
| } | ||
| clang_analyzer_dump(b + 300); // expected-warning {{310}} | ||
| return 0; | ||
| } | ||
|
|
||
| // From: https://github.com/llvm/llvm-project/pull/116462#issuecomment-2517853226 | ||
| int ternary_in_assume(int a, int b) { | ||
| // FIXME notes | ||
| // Currently, if this test is run without the core.builtin.Builtin checker, the above function with the __builtin_assume behaves identically to the following test | ||
| // i.e. calls to `clang_analyzer_dump` result in "extraneous" prints of the SVal(s) `reg<int b> ...` | ||
| // as opposed to 4 or 10 | ||
| // which likely implies the Program State(s) did not get narrowed. | ||
| // A new checker is likely needed to be implemented to properly handle the expressions within `[[assume]]` to eliminate the states where `b` is not narrowed. | ||
|
|
||
| [[assume(a > 10 ? b == 4 : b == 10)]]; | ||
| clang_analyzer_value(a); | ||
| // expected-warning@-1 {{[-2147483648, 10]}} | ||
| // expected-warning@-2 {{[11, 2147483647]}} | ||
|
|
||
| clang_analyzer_dump(b); // expected-warning {{4}} expected-warning {{10}} | ||
| // expected-warning-re@-1 {{reg_${{[0-9]+}}<int b>}} FIXME: We shouldn't have this dump. | ||
|
|
||
| if (a > 20) { | ||
| clang_analyzer_dump(b + 100); // expected-warning {{104}} | ||
| // expected-warning-re@-1 {{(reg_${{[0-9]+}}<int b>) + 100}} FIXME: We shouldn't have this dump. | ||
| return 2; | ||
| } | ||
| if (a > 10) { | ||
| clang_analyzer_dump(b + 200); // expected-warning {{204}} | ||
| // expected-warning-re@-1 {{(reg_${{[0-9]+}}<int b>) + 200}} FIXME: We shouldn't have this dump. | ||
| return 1; | ||
| } | ||
| clang_analyzer_dump(b + 300); // expected-warning {{310}} | ||
| // expected-warning-re@-1 {{(reg_${{[0-9]+}}<int b>) + 300}} FIXME: We shouldn't have this dump. | ||
| return 0; | ||
| } | ||
|
|
||
| int assume_and_fallthrough_at_the_same_attrstmt(int a, int b) { | ||
| [[assume(a == 2)]]; | ||
| clang_analyzer_dump(a); // expected-warning {{2 S32b}} | ||
| // expected-warning-re@-1 {{reg_${{[0-9]+}}<int a>}} FIXME: We shouldn't have this dump. | ||
| switch (a) { | ||
| case 2: | ||
| [[fallthrough, assume(b == 30)]]; | ||
| case 4: { | ||
| clang_analyzer_dump(b); // expected-warning {{30 S32b}} | ||
| // expected-warning-re@-1 {{reg_${{[0-9]+}}<int b>}} FIXME: We shouldn't have this dump. | ||
| return b; | ||
| } | ||
| } | ||
| // This code should be unreachable. | ||
| [[assume(false)]]; // This should definitely make it so. | ||
| clang_analyzer_dump(33); // expected-warning {{33 S32b}} | ||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,7 @@ | ||
| // RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,security.ArrayBound -verify %s | ||
| // RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -verify %s \ | ||
| // RUN: -analyzer-checker=unix,core,security.ArrayBound,debug.ExprInspection | ||
|
|
||
| void clang_analyzer_eval(bool); | ||
|
|
||
| // Tests doing an out-of-bounds access after the end of an array using: | ||
| // - constant integer index | ||
|
|
@@ -180,3 +183,58 @@ int test_reference_that_might_be_after_the_end(int idx) { | |
| return ref; | ||
| } | ||
|
|
||
| // From: https://github.com/llvm/llvm-project/issues/100762 | ||
| extern int arrOf10[10]; | ||
| void using_builtin(int x) { | ||
| __builtin_assume(x > 101); // CallExpr | ||
| arrOf10[x] = 404; // expected-warning {{Out of bound access to memory}} | ||
| } | ||
|
|
||
| void using_assume_attr(int ax) { | ||
| [[assume(ax > 100)]]; // NullStmt with an "assume" attribute. | ||
| arrOf10[ax] = 405; // expected-warning {{Out of bound access to memory}} | ||
| } | ||
|
|
||
| void using_many_assume_attr(int yx) { | ||
| [[assume(yx > 104), assume(yx > 200), assume(yx < 300)]]; // NullStmt with an attribute | ||
| arrOf10[yx] = 406; // expected-warning{{Out of bound access to memory}} | ||
| } | ||
|
|
||
|
|
||
| int using_builtin_assume_has_no_sideeffects(int y) { | ||
| // We should not apply sideeffects of the argument of [[assume(...)]]. | ||
| // "y" should not get incremented; | ||
| __builtin_assume(++y == 43); // expected-warning {{assumption is ignored because it contains (potential) side-effects}} | ||
| clang_analyzer_eval(y == 42); // expected-warning {{FALSE}} | ||
| return y; | ||
| } | ||
|
|
||
|
|
||
|
|
||
| int using_assume_attr_has_no_sideeffects(int y) { | ||
|
|
||
| // We should not apply sideeffects of the argument of [[assume(...)]]. | ||
| // "y" should not get incremented; | ||
| [[assume(++y == 43)]]; // expected-warning {{assumption is ignored because it contains (potential) side-effects}} | ||
|
|
||
| clang_analyzer_eval(y == 42); // expected-warning {{TRUE}} expected-warning {{FALSE}} FIXME: This should be only TRUE. | ||
|
|
||
| clang_analyzer_eval(y == 43); // expected-warning {{FALSE}} expected-warning {{TRUE}} FIXME: This should be only FALSE. | ||
|
|
||
| return y; | ||
| } | ||
|
|
||
|
|
||
| int using_builtinassume_has_no_sideeffects(int u) { | ||
| // We should not apply sideeffects of the argument of __builtin_assume(...) | ||
| // "u" should not get incremented; | ||
| __builtin_assume(++u == 43); // expected-warning {{assumption is ignored because it contains (potential) side-effects}} | ||
|
||
|
|
||
| // FIXME: evaluate this to true | ||
| clang_analyzer_eval(u == 42); // expected-warning {{FALSE}} current behavior | ||
|
|
||
| // FIXME: evaluate this to false | ||
| clang_analyzer_eval(u == 43); // expected-warning {{TRUE}} current behavior | ||
|
|
||
| return u; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.