================
@@ -5493,23 +5520,25 @@ TypeSourceInfo 
*TemplateDeclInstantiator::SubstFunctionType(
       // the function parameters themselves.
       const FunctionProtoType *OldProto =
           cast<FunctionProtoType>(OldProtoLoc.getType());
-      for (unsigned i = 0, i_end = OldProtoLoc.getNumParams(); i != i_end;
-           ++i) {
-        ParmVarDecl *OldParam = OldProtoLoc.getParam(i);
-        if (!OldParam) {
-          Params.push_back(SemaRef.BuildParmVarDeclForTypedef(
-              D, D->getLocation(), OldProto->getParamType(i)));
-          continue;
-        }
-
-        ParmVarDecl *Parm = SemaRef.SubstParmVarDecl(
-            OldParam, TemplateArgs, /*indexAdjustment=*/0,
-            /*NumExpansions=*/std::nullopt,
-            /*ExpectParameterPack=*/false, EvaluateConstraints);
-        if (!Parm)
-          return nullptr;
-        Params.push_back(Parm);
-      }
+      SmallVector<QualType, 4> ParamTypes;
+      Sema::ExtParameterInfoBuilder ExtParamInfos;
+      if (SemaRef.SubstParmTypes(D->getLocation(), OldProtoLoc.getParams(),
+                                 nullptr, TemplateArgs, ParamTypes, &Params,
+                                 ExtParamInfos, OldProto->param_type_begin(),
+                                 EvaluateConstraints))
+        return nullptr;
+      // Declare a parameter that was only a type in the prototype. A function
+      // declared through a typedef with an attribute that rewrites the
+      // function type in place, such as noreturn, gets a prototype whose
+      // parameters have no ParmVarDecl, so no attribute of the typedef's
+      // parameters reaches it; see TypeSpecLocFiller in SemaType.
+      // FIXME: Keep the typedef's parameters there instead. The dependent
+      // branch above returns null for such a prototype, dropping the member.
----------------
vtjnash wrote:

That's certainly a possible cause, though I think noreturn might affect 
overloads? and so we happen to know that Clang has to crash because of that, if 
it ends up instantiating a noreturn function inferred as a different overload, 
since this "no behavior change goal" is in contradiction to the part of the C++ 
spec that requires each distinguishable type must have a different mangling (so 
that different typedef don't attempt to generate into the same llvm function by 
name). This is also likely one of the hardest problems with getting TSA to be a 
type attribute. Claude wrote about that particular problem with noreturn that 
it encountered why making the typedef-capability experiment. I've mentioned it 
before, but it's specifically the "ABI hazard" it mentioned in the later 
commits it made:
 
https://github.com/vtjnash/llvm-project/blob/jn/tsa-typedef-capability/clang/docs/ThreadSafetyTypeCapabilities-Design.md#the-canonical-choice-creates-an-abi-hazard-so-the-policy-is-explicit

https://github.com/llvm/llvm-project/pull/232784
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to