Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 53de2d8

Browse files
authored
Merge pull request #830 from ian-semmle/constexpr
C++: Add Function.{isDeclaredConstexpr,isConstexpr}() predicates
2 parents bea75e2 + ad126b9 commit 53de2d8

10 files changed

Lines changed: 75 additions & 0 deletions

File tree

change-notes/1.20/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,4 @@
3636

3737
* There is a new `Namespace.isInline()` predicate, which holds if the namespace was declared as `inline namespace`.
3838
* The `Expr.isConstant()` predicate now also holds for _address constant expressions_, which are addresses that will be constant after the program has been linked. These address constants do not have a result for `Expr.getValue()`.
39+
* There are new `Function.isDeclaredConstexpr()` and `Function.isConstexpr()` predicates. They can be used to tell whether a function was declared as `constexpr`, and whether it actually is `constexpr`.

cpp/ql/src/semmle/code/cpp/Function.qll

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
103103
function_defaulted(underlyingElement(this))
104104
}
105105

106+
/**
107+
* Holds if this function is declared to be `constexpr`.
108+
*/
109+
predicate isDeclaredConstexpr() {
110+
this.hasSpecifier("declared_constexpr")
111+
}
112+
113+
/**
114+
* Holds if this function is `constexpr`. Normally, this holds if and
115+
* only if `isDeclaredConstexpr()` holds, but in some circumstances
116+
* they differ. For example, with
117+
* ```
118+
* int f(int i) { return 6; }
119+
* template <typename T> constexpr int g(T x) { return f(x); }
120+
* ```
121+
* `g<int>` is declared constexpr, but is not constexpr.
122+
*/
123+
predicate isConstexpr() {
124+
this.hasSpecifier("is_constexpr")
125+
}
126+
106127
/**
107128
* Holds if this function is declared with `__attribute__((naked))` or
108129
* `__declspec(naked)`.

cpp/ql/test/library-tests/clang_ms/element.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
| file://:0:0:0:0 | const mystruct & |
6868
| file://:0:0:0:0 | declaration of 1st parameter |
6969
| file://:0:0:0:0 | declaration of 1st parameter |
70+
| file://:0:0:0:0 | declared_constexpr |
7071
| file://:0:0:0:0 | decltype(nullptr) |
7172
| file://:0:0:0:0 | definition of fp_offset |
7273
| file://:0:0:0:0 | definition of gp_offset |
@@ -86,6 +87,7 @@
8687
| file://:0:0:0:0 | implicit_int |
8788
| file://:0:0:0:0 | inline |
8889
| file://:0:0:0:0 | int |
90+
| file://:0:0:0:0 | is_constexpr |
8991
| file://:0:0:0:0 | long |
9092
| file://:0:0:0:0 | long double |
9193
| file://:0:0:0:0 | long long |

cpp/ql/test/library-tests/conditions/elements.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
| file://:0:0:0:0 | const |
4343
| file://:0:0:0:0 | const __va_list_tag |
4444
| file://:0:0:0:0 | const __va_list_tag & |
45+
| file://:0:0:0:0 | declared_constexpr |
4546
| file://:0:0:0:0 | decltype(nullptr) |
4647
| file://:0:0:0:0 | definition of <error> |
4748
| file://:0:0:0:0 | definition of fp_offset |
@@ -63,6 +64,7 @@
6364
| file://:0:0:0:0 | initializer for <error> |
6465
| file://:0:0:0:0 | inline |
6566
| file://:0:0:0:0 | int |
67+
| file://:0:0:0:0 | is_constexpr |
6668
| file://:0:0:0:0 | long |
6769
| file://:0:0:0:0 | long double |
6870
| file://:0:0:0:0 | long long |
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
constexpr int fun_constexpr();
3+
int fun_not_constexpr();
4+
5+
constexpr int overloaded_fun(int i) {
6+
return 5;
7+
}
8+
9+
int overloaded_fun(float f) {
10+
return 6;
11+
}
12+
13+
template <typename T>
14+
constexpr int template_fun(T t) {
15+
return overloaded_fun(t);
16+
}
17+
18+
void caller(void) {
19+
int i;
20+
float f;
21+
template_fun(i);
22+
template_fun(f);
23+
}
24+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
| constexpr.cpp:2:15:2:27 | fun_constexpr | int fun_constexpr() | true | true |
2+
| constexpr.cpp:3:5:3:21 | fun_not_constexpr | int fun_not_constexpr() | false | false |
3+
| constexpr.cpp:5:15:5:28 | overloaded_fun | int overloaded_fun(int) | true | true |
4+
| constexpr.cpp:9:5:9:18 | overloaded_fun | int overloaded_fun(float) | false | false |
5+
| constexpr.cpp:14:15:14:15 | template_fun | int template_fun<float>(float) | true | false |
6+
| constexpr.cpp:14:15:14:15 | template_fun | int template_fun<int>(int) | true | true |
7+
| constexpr.cpp:14:15:14:26 | template_fun | int template_fun<T>(T) | true | true |
8+
| constexpr.cpp:18:6:18:11 | caller | void caller() | false | false |
9+
| file://:0:0:0:0 | operator= | __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) | false | false |
10+
| file://:0:0:0:0 | operator= | __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) | false | false |
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import cpp
2+
import semmle.code.cpp.Print
3+
4+
from Function f
5+
select f, getIdentityString(f),
6+
any(boolean b | if f.isDeclaredConstexpr() then b = true else b = false),
7+
any(boolean b | if f.isConstexpr() then b = true else b = false)

cpp/ql/test/library-tests/specifiers2/specifiers2.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | extern |
1212
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | inline |
1313
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | inline |
14+
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | is_constexpr |
15+
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | is_constexpr |
1416
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | public |
1517
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | public |
1618
| Function | specifiers2pp.cpp:8:7:8:7 | operator= | operator= | extern |
@@ -41,6 +43,8 @@
4143
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
4244
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
4345
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
46+
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | is_constexpr |
47+
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | is_constexpr |
4448
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |
4549
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |
4650
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |

cpp/ql/test/library-tests/templates/instantiations_functions/elements.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
| file://:0:0:0:0 | declaration of 1st parameter |
8989
| file://:0:0:0:0 | declaration of 1st parameter |
9090
| file://:0:0:0:0 | declaration of 1st parameter |
91+
| file://:0:0:0:0 | declared_constexpr |
9192
| file://:0:0:0:0 | decltype(nullptr) |
9293
| file://:0:0:0:0 | definition of fp_offset |
9394
| file://:0:0:0:0 | definition of gp_offset |
@@ -111,6 +112,7 @@
111112
| file://:0:0:0:0 | int |
112113
| file://:0:0:0:0 | int & |
113114
| file://:0:0:0:0 | int * |
115+
| file://:0:0:0:0 | is_constexpr |
114116
| file://:0:0:0:0 | long |
115117
| file://:0:0:0:0 | long double |
116118
| file://:0:0:0:0 | long long |

cpp/ql/test/library-tests/unnamed/elements.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
| file://:0:0:0:0 | char16_t | Other |
3636
| file://:0:0:0:0 | char32_t | Other |
3737
| file://:0:0:0:0 | const | Other |
38+
| file://:0:0:0:0 | declared_constexpr | Other |
3839
| file://:0:0:0:0 | decltype(nullptr) | Other |
3940
| file://:0:0:0:0 | definition of fp_offset | Other |
4041
| file://:0:0:0:0 | definition of gp_offset | Other |
@@ -56,6 +57,7 @@
5657
| file://:0:0:0:0 | int | Other |
5758
| file://:0:0:0:0 | int * | Other |
5859
| file://:0:0:0:0 | int[0] | Other |
60+
| file://:0:0:0:0 | is_constexpr | Other |
5961
| file://:0:0:0:0 | long | Other |
6062
| file://:0:0:0:0 | long double | Other |
6163
| file://:0:0:0:0 | long long | Other |

0 commit comments

Comments
 (0)