Merge pull request #830 from ian-semmle/constexpr

C++: Add Function.{isDeclaredConstexpr,isConstexpr}() predicates
This commit is contained in:
Nick Rolfe
2019-02-25 22:11:24 +00:00
committed by GitHub
10 changed files with 75 additions and 0 deletions

View File

@@ -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`.

View File

@@ -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)`.

View File

@@ -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 |

View File

@@ -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 |

View 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);
}

View File

@@ -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 |

View File

@@ -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)

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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 |