Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -72,10 +72,12 @@ - Previously invalid member variables with template parameters would crash clang. Now fixed by setting identifiers for them. This fixes `Issue 28475 (PR28101) `_. - - Now allow the `restrict` and `_Atomic` qualifiers to be used in conjunction with `__auto_type` to match the behavior in GCC. This fixes `Issue 53652 `_. +- No longer crash when specifying a variably-modified parameter type in a + function with the ``naked`` attribute. This fixes + `Issue 50541 `_. Improvements to Clang's diagnostics Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -1194,27 +1194,29 @@ } // If any of the arguments have a variably modified type, make sure to - // emit the type size. - for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); - i != e; ++i) { - const VarDecl *VD = *i; - - // Dig out the type as written from ParmVarDecls; it's unclear whether - // the standard (C99 6.9.1p10) requires this, but we're following the - // precedent set by gcc. - QualType Ty; - if (const ParmVarDecl *PVD = dyn_cast(VD)) - Ty = PVD->getOriginalType(); - else - Ty = VD->getType(); + // emit the type size, but only if the function is not naked. Naked functions + // have no prolog to run this evaluation. + if (!FD || !FD->hasAttr()) { + for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); + i != e; ++i) { + const VarDecl *VD = *i; + + // Dig out the type as written from ParmVarDecls; it's unclear whether + // the standard (C99 6.9.1p10) requires this, but we're following the + // precedent set by gcc. + QualType Ty; + if (const ParmVarDecl *PVD = dyn_cast(VD)) + Ty = PVD->getOriginalType(); + else + Ty = VD->getType(); - if (Ty->isVariablyModifiedType()) - EmitVariablyModifiedType(Ty); + if (Ty->isVariablyModifiedType()) + EmitVariablyModifiedType(Ty); + } } // Emit a location at the end of the prologue. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitLocation(Builder, StartLoc); - // TODO: Do we need to handle this in two places like we do with // target-features/target-cpu? if (CurFuncDecl) Index: clang/test/CodeGen/attr-naked.c =================================================================== --- clang/test/CodeGen/attr-naked.c +++ clang/test/CodeGen/attr-naked.c @@ -23,5 +23,14 @@ // CHECK: unreachable } +// Make sure naked functions do not attempt to evaluate parameters with a +// variably-modified type. Naked functions get no prolog, so this evaluation +// should not take place. +__attribute__((naked)) void t4(int len, char x[len]) { + // CHECK: define{{.*}} void @t4(i32 noundef %0, i8* noundef %1) + // CHECK-NEXT: entry: + // CHECK-NEXT: unreachable +} + // CHECK: attributes [[NAKED_OPTNONE]] = { naked noinline nounwind optnone{{.*}} } // CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }