forked from OSchip/llvm-project
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:
parent
5ee88e0ba5
commit
488c772920
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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{{.*}} }
|
||||
|
|
Loading…
Reference in New Issue