Skip to content

Commit

Permalink
[clang] Fix designated initializers inside templates (llvm#69712)
Browse files Browse the repository at this point in the history
Skip anonymous members when rebuilding `DesignatedInitExpr` since
designated inits for them are meant to be created during
`InitListChecker::CheckDesignatedInitializer` routine.

Fixes llvm#65143
  • Loading branch information
Fznamznon authored and ahatanaka committed Nov 7, 2023
1 parent 5bfa5ad commit 0acbc53
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,9 @@ Bug Fixes in This Version
``thread_local`` instead of ``_Thread_local``.
Fixes (`#70068 <https://github.com/llvm/llvm-project/issues/70068>`_) and
(`#69167 <https://github.com/llvm/llvm-project/issues/69167>`_)
- Clang now accepts anonymous members initialized with designated initializers
inside templates.
Fixes (`#65143 <https://github.com/llvm/llvm-project/issues/65143>`_)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -11722,21 +11722,23 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
bool ExprChanged = false;
for (const DesignatedInitExpr::Designator &D : E->designators()) {
if (D.isFieldDesignator()) {
Desig.AddDesignator(Designator::CreateFieldDesignator(
D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
if (D.getFieldDecl()) {
FieldDecl *Field = cast_or_null<FieldDecl>(
getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
if (Field != D.getFieldDecl())
// Rebuild the expression when the transformed FieldDecl is
// different to the already assigned FieldDecl.
ExprChanged = true;
if (Field->isAnonymousStructOrUnion())
continue;
} else {
// Ensure that the designator expression is rebuilt when there isn't
// a resolved FieldDecl in the designator as we don't want to assign
// a FieldDecl to a pattern designator that will be instantiated again.
ExprChanged = true;
}
Desig.AddDesignator(Designator::CreateFieldDesignator(
D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
continue;
}

Expand Down
23 changes: 21 additions & 2 deletions clang/test/SemaCXX/cxx2b-designated-initializers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,36 @@ union S {
};

void f(int x, auto) {
const S result { // expected-error {{field designator (null) does not refer to any field in type 'const S'}}
const S result {
.a = x
};
}

void g(void) {
f(0, 0); // expected-note {{in instantiation of function template specialization 'PR61118::f<int>' requested here}}
f(0, 0);
}

} // end namespace PR61118

namespace GH65143 {
struct Inner {
int a;
};

struct Outer {
struct {
Inner inner;
};
};

template <int val> void f() {
constexpr Outer x{.inner = {val}};
static_assert(x.inner.a == val);
}

void bar() { f<4>(); }
}

namespace GH62156 {
union U1 {
int x;
Expand Down

0 comments on commit 0acbc53

Please sign in to comment.