Fix a crash with variably-modified parameter types in a naked function

Naked functions have no prolog, so it's not valid to emit prolog code
to evaluate the variably-modified type. This fixes Issue 50541.
This commit is contained in:
Aaron Ballman 2022-03-24 10:38:37 -04:00
parent 5ee88e0ba5
commit 488c772920
3 changed files with 26 additions and 17 deletions

View File

@ -72,10 +72,12 @@ Bug Fixes
- Previously invalid member variables with template parameters would crash clang.
Now fixed by setting identifiers for them.
This fixes `Issue 28475 (PR28101) <https://github.com/llvm/llvm-project/issues/28475>`_.
- 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 <https://github.com/llvm/llvm-project/issues/53652>`_.
- No longer crash when specifying a variably-modified parameter type in a
function with the ``naked`` attribute. This fixes
`Issue 50541 <https://github.com/llvm/llvm-project/issues/50541>`_.
Improvements to Clang's diagnostics

View File

@ -1195,27 +1195,26 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
}
// 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;
// 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<NakedAttr>()) {
for (const VarDecl *VD : Args) {
// 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<ParmVarDecl>(VD))
Ty = PVD->getOriginalType();
else
Ty = VD->getType();
// 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<ParmVarDecl>(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)

View File

@ -23,5 +23,13 @@ __attribute((naked)) void t3(int x) {
// 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{{.*}}, i8* noundef{{.*}})
// CHECK: unreachable
}
// CHECK: attributes [[NAKED_OPTNONE]] = { naked noinline nounwind optnone{{.*}} }
// CHECK: attributes [[NAKED]] = { naked noinline nounwind{{.*}} }