mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Merge pull request #830 from ian-semmle/constexpr
C++: Add Function.{isDeclaredConstexpr,isConstexpr}() predicates
This commit is contained in:
@@ -36,3 +36,4 @@
|
||||
|
||||
* There is a new `Namespace.isInline()` predicate, which holds if the namespace was declared as `inline namespace`.
|
||||
* 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()`.
|
||||
* 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`.
|
||||
|
||||
@@ -103,6 +103,27 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
function_defaulted(underlyingElement(this))
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this function is declared to be `constexpr`.
|
||||
*/
|
||||
predicate isDeclaredConstexpr() {
|
||||
this.hasSpecifier("declared_constexpr")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this function is `constexpr`. Normally, this holds if and
|
||||
* only if `isDeclaredConstexpr()` holds, but in some circumstances
|
||||
* they differ. For example, with
|
||||
* ```
|
||||
* int f(int i) { return 6; }
|
||||
* template <typename T> constexpr int g(T x) { return f(x); }
|
||||
* ```
|
||||
* `g<int>` is declared constexpr, but is not constexpr.
|
||||
*/
|
||||
predicate isConstexpr() {
|
||||
this.hasSpecifier("is_constexpr")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this function is declared with `__attribute__((naked))` or
|
||||
* `__declspec(naked)`.
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
| file://:0:0:0:0 | const mystruct & |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declared_constexpr |
|
||||
| file://:0:0:0:0 | decltype(nullptr) |
|
||||
| file://:0:0:0:0 | definition of fp_offset |
|
||||
| file://:0:0:0:0 | definition of gp_offset |
|
||||
@@ -86,6 +87,7 @@
|
||||
| file://:0:0:0:0 | implicit_int |
|
||||
| file://:0:0:0:0 | inline |
|
||||
| file://:0:0:0:0 | int |
|
||||
| file://:0:0:0:0 | is_constexpr |
|
||||
| file://:0:0:0:0 | long |
|
||||
| file://:0:0:0:0 | long double |
|
||||
| file://:0:0:0:0 | long long |
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
| file://:0:0:0:0 | const |
|
||||
| file://:0:0:0:0 | const __va_list_tag |
|
||||
| file://:0:0:0:0 | const __va_list_tag & |
|
||||
| file://:0:0:0:0 | declared_constexpr |
|
||||
| file://:0:0:0:0 | decltype(nullptr) |
|
||||
| file://:0:0:0:0 | definition of <error> |
|
||||
| file://:0:0:0:0 | definition of fp_offset |
|
||||
@@ -63,6 +64,7 @@
|
||||
| file://:0:0:0:0 | initializer for <error> |
|
||||
| file://:0:0:0:0 | inline |
|
||||
| file://:0:0:0:0 | int |
|
||||
| file://:0:0:0:0 | is_constexpr |
|
||||
| file://:0:0:0:0 | long |
|
||||
| file://:0:0:0:0 | long double |
|
||||
| file://:0:0:0:0 | long long |
|
||||
|
||||
24
cpp/ql/test/library-tests/functions/constexpr/constexpr.cpp
Normal file
24
cpp/ql/test/library-tests/functions/constexpr/constexpr.cpp
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
constexpr int fun_constexpr();
|
||||
int fun_not_constexpr();
|
||||
|
||||
constexpr int overloaded_fun(int i) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
int overloaded_fun(float f) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr int template_fun(T t) {
|
||||
return overloaded_fun(t);
|
||||
}
|
||||
|
||||
void caller(void) {
|
||||
int i;
|
||||
float f;
|
||||
template_fun(i);
|
||||
template_fun(f);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
| constexpr.cpp:2:15:2:27 | fun_constexpr | int fun_constexpr() | true | true |
|
||||
| constexpr.cpp:3:5:3:21 | fun_not_constexpr | int fun_not_constexpr() | false | false |
|
||||
| constexpr.cpp:5:15:5:28 | overloaded_fun | int overloaded_fun(int) | true | true |
|
||||
| constexpr.cpp:9:5:9:18 | overloaded_fun | int overloaded_fun(float) | false | false |
|
||||
| constexpr.cpp:14:15:14:15 | template_fun | int template_fun<float>(float) | true | false |
|
||||
| constexpr.cpp:14:15:14:15 | template_fun | int template_fun<int>(int) | true | true |
|
||||
| constexpr.cpp:14:15:14:26 | template_fun | int template_fun<T>(T) | true | true |
|
||||
| constexpr.cpp:18:6:18:11 | caller | void caller() | false | false |
|
||||
| file://:0:0:0:0 | operator= | __va_list_tag& __va_list_tag::operator=(__va_list_tag const&) | false | false |
|
||||
| file://:0:0:0:0 | operator= | __va_list_tag& __va_list_tag::operator=(__va_list_tag&&) | false | false |
|
||||
@@ -0,0 +1,7 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.Print
|
||||
|
||||
from Function f
|
||||
select f, getIdentityString(f),
|
||||
any(boolean b | if f.isDeclaredConstexpr() then b = true else b = false),
|
||||
any(boolean b | if f.isConstexpr() then b = true else b = false)
|
||||
@@ -11,6 +11,8 @@
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | extern |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | inline |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | inline |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | is_constexpr |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | is_constexpr |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | public |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | MyClass | MyClass | public |
|
||||
| Function | specifiers2pp.cpp:8:7:8:7 | operator= | operator= | extern |
|
||||
@@ -41,6 +43,8 @@
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | inline |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | is_constexpr |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | is_constexpr |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |
|
||||
| Function | specifiers2pp.cpp:24:7:24:7 | MyClass2 | MyClass2 | public |
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declaration of 1st parameter |
|
||||
| file://:0:0:0:0 | declared_constexpr |
|
||||
| file://:0:0:0:0 | decltype(nullptr) |
|
||||
| file://:0:0:0:0 | definition of fp_offset |
|
||||
| file://:0:0:0:0 | definition of gp_offset |
|
||||
@@ -111,6 +112,7 @@
|
||||
| file://:0:0:0:0 | int |
|
||||
| file://:0:0:0:0 | int & |
|
||||
| file://:0:0:0:0 | int * |
|
||||
| file://:0:0:0:0 | is_constexpr |
|
||||
| file://:0:0:0:0 | long |
|
||||
| file://:0:0:0:0 | long double |
|
||||
| file://:0:0:0:0 | long long |
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
| file://:0:0:0:0 | char16_t | Other |
|
||||
| file://:0:0:0:0 | char32_t | Other |
|
||||
| file://:0:0:0:0 | const | Other |
|
||||
| file://:0:0:0:0 | declared_constexpr | Other |
|
||||
| file://:0:0:0:0 | decltype(nullptr) | Other |
|
||||
| file://:0:0:0:0 | definition of fp_offset | Other |
|
||||
| file://:0:0:0:0 | definition of gp_offset | Other |
|
||||
@@ -56,6 +57,7 @@
|
||||
| file://:0:0:0:0 | int | Other |
|
||||
| file://:0:0:0:0 | int * | Other |
|
||||
| file://:0:0:0:0 | int[0] | Other |
|
||||
| file://:0:0:0:0 | is_constexpr | Other |
|
||||
| file://:0:0:0:0 | long | Other |
|
||||
| file://:0:0:0:0 | long double | Other |
|
||||
| file://:0:0:0:0 | long long | Other |
|
||||
|
||||
Reference in New Issue
Block a user