From cd8e9a1eced851de066ef19d08d8c3394d9f5f14 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 24 Aug 2020 11:39:41 +0200 Subject: [PATCH 1/2] C++: Demonstrate that constexpr implies const This test shows that a member function declared `constexpr` also gets a `const` specifier. --- .../specifiers2/specifiers2.expected | 18 ++++++++++++++++++ .../specifiers2/specifiers2pp.cpp | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/cpp/ql/test/library-tests/specifiers2/specifiers2.expected b/cpp/ql/test/library-tests/specifiers2/specifiers2.expected index 4930fdac7208..f1ecb7e2cdd1 100644 --- a/cpp/ql/test/library-tests/specifiers2/specifiers2.expected +++ b/cpp/ql/test/library-tests/specifiers2/specifiers2.expected @@ -79,6 +79,24 @@ | Function | specifiers2pp.cpp:41:16:41:23 | someFun2 | someFun2 | extern | | Function | specifiers2pp.cpp:43:9:43:16 | someFun3 | someFun3 | extern | | Function | specifiers2pp.cpp:44:16:44:23 | someFun4 | someFun4 | static | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | extern | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | extern | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | inline | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | inline | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | is_constexpr | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | is_constexpr | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | public | +| Function | specifiers2pp.cpp:62:7:62:7 | operator= | operator= | public | +| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | const | +| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | declared_constexpr | +| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | inline | +| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | is_constexpr | +| Function | specifiers2pp.cpp:63:19:63:34 | member_constexpr | member_constexpr | private | +| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | const | +| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | declared_constexpr | +| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | inline | +| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | is_constexpr | +| Function | specifiers2pp.cpp:64:19:64:40 | member_const_constexpr | member_const_constexpr | private | | FunctionDeclarationEntry | specifiers2.c:11:6:11:6 | declaration of f | f | c_linkage | | FunctionDeclarationEntry | specifiers2.c:11:6:11:6 | declaration of f | f | void_param_list | | FunctionDeclarationEntry | specifiers2.c:12:13:12:13 | declaration of f | f | c_linkage | diff --git a/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp b/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp index 7bceb782ecaf..2f7a429a7e65 100644 --- a/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp +++ b/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp @@ -58,3 +58,8 @@ template using Const = const T; using Const_int = Const; typedef volatile Const_int volatile_Const_int; + +class TestConstexpr { + constexpr int member_constexpr() { return 0; } + constexpr int member_const_constexpr() const { return 0; } +}; From b2cd98a98f6312f9c7ec0f33c59a0b2f5e9f7e80 Mon Sep 17 00:00:00 2001 From: Jonas Jensen Date: Mon, 24 Aug 2020 13:42:40 +0200 Subject: [PATCH 2/2] C++: Confirm correct behaviour on C++20 Making `constexpr` imply `const` was correct for C++11 and was a correct emulation of a GCC bug on GCC < 5.0. This test confirms that the problem isn't there in C++20. --- cpp/ql/test/library-tests/specifiers2/cpp20.cpp | 10 ++++++++++ .../specifiers2/specifiers2.expected | 17 +++++++++++++++++ .../library-tests/specifiers2/specifiers2pp.cpp | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 cpp/ql/test/library-tests/specifiers2/cpp20.cpp diff --git a/cpp/ql/test/library-tests/specifiers2/cpp20.cpp b/cpp/ql/test/library-tests/specifiers2/cpp20.cpp new file mode 100644 index 000000000000..d260eaecf813 --- /dev/null +++ b/cpp/ql/test/library-tests/specifiers2/cpp20.cpp @@ -0,0 +1,10 @@ +// semmle-extractor-options: --edg --clang --edg --c++20 + +namespace cpp20 { + +class TestConstexpr { + constexpr int member_constexpr() { return 0; } // not const in C++ >= 14 + constexpr int member_const_constexpr() const { return 0; } +}; + +} // namespace cpp20 diff --git a/cpp/ql/test/library-tests/specifiers2/specifiers2.expected b/cpp/ql/test/library-tests/specifiers2/specifiers2.expected index f1ecb7e2cdd1..2ccfc7b84a02 100644 --- a/cpp/ql/test/library-tests/specifiers2/specifiers2.expected +++ b/cpp/ql/test/library-tests/specifiers2/specifiers2.expected @@ -1,5 +1,22 @@ | Class | specifiers2pp.cpp:8:7:8:13 | MyClass | MyClass | abstract | | Class | specifiers2pp.cpp:24:7:24:14 | MyClass2 | MyClass2 | abstract | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | extern | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | extern | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | inline | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | inline | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | is_constexpr | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | is_constexpr | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | public | +| Function | cpp20.cpp:5:7:5:7 | operator= | operator= | public | +| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | declared_constexpr | +| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | inline | +| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | is_constexpr | +| Function | cpp20.cpp:6:19:6:34 | member_constexpr | member_constexpr | private | +| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | const | +| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | declared_constexpr | +| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | inline | +| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | is_constexpr | +| Function | cpp20.cpp:7:19:7:40 | member_const_constexpr | member_const_constexpr | private | | Function | specifiers2.c:11:6:11:6 | f | f | extern | | Function | specifiers2.c:12:13:12:13 | f | f | extern | | Function | specifiers2.c:13:13:13:13 | f | f | extern | diff --git a/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp b/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp index 2f7a429a7e65..37d5e894c889 100644 --- a/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp +++ b/cpp/ql/test/library-tests/specifiers2/specifiers2pp.cpp @@ -60,6 +60,6 @@ using Const_int = Const; typedef volatile Const_int volatile_Const_int; class TestConstexpr { - constexpr int member_constexpr() { return 0; } + constexpr int member_constexpr() { return 0; } // const in C++11 constexpr int member_const_constexpr() const { return 0; } };