summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorkaizhangNV <149626564+kaizhangNV@users.noreply.github.com>2025-03-06 22:38:28 -0600
committerGitHub <noreply@github.com>2025-03-06 20:38:28 -0800
commite1952dc8cf8f5b62d00ce114e353c5390cc6c37a (patch)
tree3c04706cb3c110fcf2f65f11eca8d37dcd42dcf1 /source
parent9d7d943db47dd7805a710431cf7eedc0bec8ecc7 (diff)
Fix a bug in default ctor synthesizing (#6527)
* Fix a bug in default ctor synthesizing - This is fix for the implementation bug, when a struct has explicit ctor we should not synthesize the default ctor anymore. - When invoke the synthesized ctor converted from initializer list, we should check if the struct is a c-style type if it struct has no synthesized ctor. In this case we should report error because it's invalid to use initializer list here. - The only exception is the unsized array, we still have to fall back to use the legacy initializer list logic to initialize the unsized array until we formalize a proper solution. - update test.
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-conversion.cpp29
-rw-r--r--source/slang/slang-check-decl.cpp2
2 files changed, 26 insertions, 5 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index c5cf192ee..1c8846e66 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -396,14 +396,35 @@ bool SemanticsVisitor::createInvokeExprForSynthesizedCtor(
{
StructDecl* structDecl = isDeclRefTypeOf<StructDecl>(toType).getDecl();
- if (!structDecl || !_getSynthesizedConstructor(
- structDecl,
- ConstructorDecl::ConstructorFlavor::SynthesizedDefault))
+ if (!structDecl)
return false;
HashSet<Type*> isVisit;
- bool isCStyle = isCStyleType(toType, isVisit);
+ bool isCStyle = false;
+ if (!_getSynthesizedConstructor(
+ structDecl,
+ ConstructorDecl::ConstructorFlavor::SynthesizedDefault))
+ {
+ // When a struct has no constructor and it's not a C-style type, the initializer list is
+ // invalid.
+ isCStyle = isCStyleType(toType, isVisit);
+
+ // WAR: We currently still has to allow legacy initializer list for array type until we have
+ // more proper solution for array initialization, so if the right hand side is an array
+ // type, we will not report error and fall-back to legacy initializer list logic.
+ bool isArrayType = as<ArrayExpressionType>(toType) != nullptr;
+ if (!isCStyle && !isArrayType)
+ {
+ getSink()->diagnose(
+ fromInitializerListExpr->loc,
+ Diagnostics::cannotUseInitializerListForType,
+ toType);
+ }
+
+ return false;
+ }
+ isCStyle = isCStyleType(toType, isVisit);
// TODO: This is just a special case for a backwards-compatibility feature
// for HLSL, this flag will imply that the initializer list is synthesized
// for a type cast from a literal zero to a 'struct'. In this case, we will fall
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 5ee8ba3ef..34143ad75 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -12412,7 +12412,7 @@ bool SemanticsDeclAttributesVisitor::_synthesizeCtorSignature(StructDecl* struct
// any constructors. see:
// https://github.com/shader-slang/slang/blob/master/docs/proposals/004-initialization.md#inheritance-initialization
if (_hasExplicitConstructor(structDecl, true))
- return false;
+ return true;
// synthesize the signature first.
// The constructor's visibility level is the same as the struct itself.