Repository navigation
keep C++11 constexpr templates with C++14-style statements usable as constants in GNU and Clang modes, fix for [GH #356] #386
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
Open
mohitmishra786
wants to merge
2
commits into
edgcpp:main
Choose a base branch
from
mohitmishra786:gh-356-cpp11-constexpr-cpp14-body
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+177
−7
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| [GH #356] | ||
| C++11 constexpr templates with C++14-style statements | ||
|
|
||
| In GNU (12.0 and later) and Clang (3.3 and later) C++11 modes, a statement | ||
| that C++14 allows in a constexpr constructor or function of a template (an | ||
| "if" statement, for example) is accepted with a warning. The constructor or | ||
| function was nevertheless treated as not constexpr, so it could not be used | ||
| in constant expressions. For example, with --c++11 --gnu_version 150000: | ||
|
|
||
| template <class T> struct A { | ||
| T x; | ||
| constexpr A(T i) : x(i) { | ||
| if (sizeof(T) == 0) {} // Warning | ||
| } | ||
| }; | ||
| constexpr A<int> a(5); // Previously an error. | ||
|
|
||
| This is now fixed for constexpr constructors and, in Clang mode (like | ||
| Clang), for constexpr functions. As with GCC, such a constexpr function | ||
| still cannot be used in constant expressions in GNU mode. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| fe_only -DTEST_NUMBER=1 --c++11 --gnu_version 150000 Test_name.c | ||
| "Test_name.c", line 15: warning: statement may not appear in a constexpr constructor | ||
| if (sizeof(T) == 0) {} | ||
| ^ | ||
|
|
||
| "Test_name.c", line 24: warning: statement may not appear in a constexpr constructor | ||
| constexpr B(T i) : x(i) { return; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 31: warning: statement may not appear in a constexpr function | ||
| if (t > 0) {} | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 35: error: expression must have a constant value | ||
| static_assert(f(1) == 1, ""); // Error in GNU mode only. | ||
| ^ | ||
| "Test_name.c", line 35: note: this call cannot be evaluated because the target function function "f(T) [with T=int]" (declared at line 30) is not constexpr or not completely defined yet | ||
| static_assert(f(1) == 1, ""); // Error in GNU mode only. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 39: warning: statement may not appear in a constexpr function | ||
| goto done; | ||
| ^ | ||
|
|
||
| "Test_name.c", line 40: warning: statement may not appear in a constexpr function | ||
| done: | ||
| ^ | ||
|
|
||
| "Test_name.c", line 43: error: expression must have a constant value | ||
| static_assert(g(1) == 1, ""); // Error: g is not usable here. | ||
| ^ | ||
| "Test_name.c", line 43: note: this call cannot be evaluated because the target function function "g(T) [with T=int]" (declared at line 38) is not constexpr or not completely defined yet | ||
| static_assert(g(1) == 1, ""); // Error: g is not usable here. | ||
| ^ | ||
|
|
||
| 2 errors detected in the compilation of "Test_name.c". |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| fe_only -DTEST_NUMBER=2 --c++11 --clang_version 190000 Test_name.c | ||
| "Test_name.c", line 15: warning: statement may not appear in a constexpr constructor | ||
| if (sizeof(T) == 0) {} | ||
| ^ | ||
|
|
||
| "Test_name.c", line 24: warning: statement may not appear in a constexpr constructor | ||
| constexpr B(T i) : x(i) { return; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 31: warning: statement may not appear in a constexpr function | ||
| if (t > 0) {} | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 32: warning: statement may not appear in a constexpr function | ||
| switch (sizeof(T)) { default: break; } | ||
| ^ | ||
|
|
||
| "Test_name.c", line 39: warning: statement may not appear in a constexpr function | ||
| goto done; | ||
| ^ | ||
|
|
||
| "Test_name.c", line 40: warning: statement may not appear in a constexpr function | ||
| done: | ||
| ^ | ||
|
|
||
| "Test_name.c", line 43: error: expression must have a constant value | ||
| static_assert(g(1) == 1, ""); // Error: g is not usable here. | ||
| ^ | ||
| "Test_name.c", line 43: note: this call cannot be evaluated because the target function function "g(T) [with T=int]" (declared at line 38) is not constexpr or not completely defined yet | ||
| static_assert(g(1) == 1, ""); // Error: g is not usable here. | ||
| ^ | ||
|
|
||
| 1 error detected in the compilation of "Test_name.c". |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| //type:fn | ||
| //options:--c++11 --gnu_version 150000:--c++11 --clang_version 190000 | ||
| //remark:[GH #356] C++11 constexpr template with a C++14-style body | ||
| // | ||
| // In GNU and Clang C++11 modes, a statement that C++14 allows in a constexpr | ||
| // constructor of a template only gets a warning, and the constructor can | ||
| // still be used in constant expressions. For a constexpr function template, | ||
| // that is only the case in Clang mode (GCC rejects the call). A goto, which | ||
| // C++14 does not allow either, makes the function unusable in both modes. | ||
|
|
||
| template <class T> | ||
| struct A { | ||
| T x; | ||
| constexpr A(T i) : x(i) { | ||
| if (sizeof(T) == 0) {} | ||
| } | ||
| }; | ||
| constexpr A<int> a(5); | ||
| static_assert(a.x == 5, ""); | ||
|
|
||
| template <class T> | ||
| struct B { | ||
| T x; | ||
| constexpr B(T i) : x(i) { return; } | ||
| }; | ||
| constexpr B<int> b(6); | ||
| static_assert(b.x == 6, ""); | ||
|
|
||
| template <class T> | ||
| constexpr int f(T t) { | ||
| if (t > 0) {} | ||
| switch (sizeof(T)) { default: break; } | ||
| return 1; | ||
| } | ||
| static_assert(f(1) == 1, ""); // Error in GNU mode only. | ||
|
|
||
| template <class T> | ||
| constexpr int g(T t) { | ||
| goto done; | ||
| done: | ||
| return 1; | ||
| } | ||
| static_assert(g(1) == 1, ""); // Error: g is not usable here. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.