Skip to content

Commit

Permalink
[Clang] Fix the location of default init expressions
Browse files Browse the repository at this point in the history
Default member initializations constructed from
a parenthesized aggregate initialization should be constructed
at the location of the left paren, to be consistent with
brace initialization.
Otherwise we get diagmostics and source_location in the wrong places.

Fixes #63903

Reviewed By: aaron.ballman, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D155573
  • Loading branch information
cor3ntin committed Jul 19, 2023
1 parent 036a1b2 commit 64cfcde
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,9 @@ Bug Fixes to C++ Support
- Merge lambdas in require expressions in standard C++ modules.
(`#63544 <https://github.com/llvm/llvm-project/issues/63544>`_)

- Fix location of default member initialization in parenthesized aggregate
initialization.
(`#63903 <https://github.com/llvm/llvm-project/issues/63903>`_)

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5593,7 +5593,8 @@ static void TryOrBuildParenListInitialization(
// C++ [dcl.init]p16.6.2.2
// The remaining elements are initialized with their default
// member initializers, if any
ExprResult DIE = S.BuildCXXDefaultInitExpr(FD->getLocation(), FD);
ExprResult DIE = S.BuildCXXDefaultInitExpr(
Kind.getParenOrBraceRange().getEnd(), FD);
if (DIE.isInvalid())
return;
S.checkInitializerLifetime(SubEntity, DIE.get());
Expand Down
11 changes: 11 additions & 0 deletions clang/test/SemaCXX/paren-list-agg-init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,3 +299,14 @@ namespace gh63758 {
struct S {} s;
auto words = (char[])s; // expected-error {{C-style cast from 'struct S' to 'char[]' is not allowed}}
};

namespace GH63903 {
constexpr int f(); // expected-note {{declared here}}
struct S {
int a = 0, b = f(); // expected-note {{undefined function 'f' cannot be used in a constant expression}}
};

// Test that errors produced by default members are produced at the location of the initialization
constexpr S s(0); // beforecxx20-warning {{aggregate initialization of type 'const S' from a parenthesized list of values is a C++20 extension}} \
// expected-error {{constexpr variable 's' must be initialized by a constant expression}}
}
18 changes: 18 additions & 0 deletions clang/test/SemaCXX/source_location.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fexceptions -verify %s
// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -DUSE_CONSTEVAL -fexceptions -verify %s
// RUN: %clang_cc1 -std=c++2b -fcxx-exceptions -DUSE_CONSTEVAL -DPAREN_INIT -fexceptions -verify %s
// RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fms-extensions -DMS -fexceptions -verify %s
// RUN: %clang_cc1 -std=c++2a -fcxx-exceptions -fms-extensions -DMS -DUSE_CONSTEVAL -fexceptions -verify %s
// expected-no-diagnostics
Expand Down Expand Up @@ -781,3 +782,20 @@ constexpr int f(int i = G<T>{}.line) {
static_assert(f<int>() != // intentional new line
f<int>());
}

#ifdef PAREN_INIT
namespace GH63903 {
struct S {
int _;
int i = SL::current().line();
int j = __builtin_LINE();
};
// Ensure parent aggregate initialization is consistent with brace
// aggregate initialization.
// Note: consteval functions are evaluated where they are used.
static_assert(S(0).i == __builtin_LINE());
static_assert(S(0).i == S{0}.i);
static_assert(S(0).j == S{0}.j);
static_assert(S(0).j == S{0}.i);
}
#endif

0 comments on commit 64cfcde

Please sign in to comment.