Repository navigation
make returning a reference bound to a temporary an error in C++26 (P2748), fix for [GH #106] #388
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
4
commits into
edgcpp:main
Choose a base branch
from
mohitmishra786:gh-106-return-ref-to-temporary
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.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
a9df0c7
Make returning a reference bound to a temporary an error in C++26. [G…
mohitmishra786 eb3d528
Keep the C++26 return-temporary error off direct bindings to similar …
mohitmishra786 f101ddc
Exempt the is_convertible check from P2748 and diagnose references to…
mohitmishra786 bd64eba
Detect returning a reference to a member of a call result or to a tem…
mohitmishra786 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
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
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
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 #106] | ||
| C++26: returning a reference bound to a temporary is not allowed | ||
|
|
||
| A return statement that binds the returned reference to a temporary is not | ||
| allowed in C++26 (P2748). The front end only issued a warning. It is now an | ||
| error in C++26 (still a warning when emulating GCC versions before 14 or | ||
| Clang versions before 19, which do the same). For example, with --c++26: | ||
|
|
||
| struct S { int x; }; | ||
| const int& f() { return 1; } // Now an error. | ||
| const int& g() { return S().x; } // Now an error. | ||
|
|
||
| Returning a reference to a member of a temporary, as in g, was previously not | ||
| diagnosed at all in the standard (non-GNU, non-Clang) modes; before C++26 it | ||
| now gets the same warning as the other cases. Returning a reference to a | ||
| local variable is still only a warning. | ||
|
|
||
| As P2748 specifies, this does not apply to the conversion checked by | ||
| std::is_convertible (e.g., __is_convertible_to(long, const int&) is still | ||
| true). |
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,30 @@ | ||
| fe_only -DTEST_NUMBER=1 --c++26 Test_name.c | ||
| "Test_name.c", line 11: error: returning reference to local temporary | ||
| const int& f1() { return 1; } // Temporary: diagnosed. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 12: error: returning reference to local temporary | ||
| const int& f2(long l) { return l; } // Temporary from a conversion. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 13: error: returning reference to local temporary | ||
| const int& f3() { return S().x; } // Member of a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: error: returning reference to local temporary | ||
| int&& f4() { return 1; } // Rvalue reference to a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 15: warning: returning reference to local variable | ||
| const int& f5() { int i = 0; return i; } // Local variable: only a warning. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 17: error: returning reference to local temporary | ||
| const int& f7() { return make().x; } // Member of a call's result. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 19: error: returning reference to local temporary | ||
| return b ? static_cast<int&&>(i) : S().x; | ||
| ^ | ||
|
|
||
| 6 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,34 @@ | ||
| fe_only -DTEST_NUMBER=2 --c++26 --gnu_version 140000 Test_name.c | ||
| "Test_name.c", line 11: error: returning reference to local temporary | ||
| const int& f1() { return 1; } // Temporary: diagnosed. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 12: error: returning reference to local temporary | ||
| const int& f2(long l) { return l; } // Temporary from a conversion. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 13: error: returning reference to local temporary | ||
| const int& f3() { return S().x; } // Member of a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: error: returning reference to local temporary | ||
| int&& f4() { return 1; } // Rvalue reference to a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 15: warning: returning reference to local variable | ||
| const int& f5() { int i = 0; return i; } // Local variable: only a warning. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 17: error: returning reference to local temporary | ||
| const int& f7() { return make().x; } // Member of a call's result. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 19: error: returning reference to local temporary | ||
| return b ? static_cast<int&&>(i) : S().x; | ||
| ^ | ||
|
|
||
| "Test_name.c", line 25: warning: returning reference to local temporary | ||
| const int *const *const &f6() { return pp; } | ||
| ^ | ||
|
|
||
| 6 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,34 @@ | ||
| fe_only -DTEST_NUMBER=3 --c++26 --clang_version 190000 Test_name.c | ||
| "Test_name.c", line 11: error: returning reference to local temporary | ||
| const int& f1() { return 1; } // Temporary: diagnosed. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 12: error: returning reference to local temporary | ||
| const int& f2(long l) { return l; } // Temporary from a conversion. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 13: error: returning reference to local temporary | ||
| const int& f3() { return S().x; } // Member of a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 14: error: returning reference to local temporary | ||
| int&& f4() { return 1; } // Rvalue reference to a temporary. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 15: warning: returning reference to local variable | ||
| const int& f5() { int i = 0; return i; } // Local variable: only a warning. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 17: error: returning reference to local temporary | ||
| const int& f7() { return make().x; } // Member of a call's result. | ||
| ^ | ||
|
|
||
| "Test_name.c", line 19: error: returning reference to local temporary | ||
| return b ? static_cast<int&&>(i) : S().x; | ||
| ^ | ||
|
|
||
| "Test_name.c", line 25: warning: returning reference to local temporary | ||
| const int *const *const &f6() { return pp; } | ||
| ^ | ||
|
|
||
| 6 errors detected in the compilation of "Test_name.c". |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Script executed:
Repository: edgcpp/compiler
Length of output: 42304
Traverse and classify array prvalues during temporary searches.
The
A&& f() { return A{1, 2}; }path reacheseok_array_to_pointerwith a non-glvalue array operand. The walker skips that operand. Even if it traverses the operand,examine_expr_for_auto_objectadmits only glvalues and class prvalues, so it ignores the non-class array temporary. The return-reference check therefore misses the required C++26 diagnostic.Both changes are required. Gate both changes on
look_for_temporaries;is_glvalue_for_auto_objectleaves that flag false, so legacy automatic-object queries remain unchanged.Suggested fix