[clang] 488c772 - Fix a crash with variably-modified parameter types in a naked function
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 24 07:39:24 PDT 2022
Author: Aaron Ballman
Date: 2022-03-24T10:39:14-04:00
New Revision: 488c772920566354075f7933eedbe4358c128bd2
URL: https://github.com/llvm/llvm-project/commit/488c772920566354075f7933eedbe4358c128bd2
DIFF: https://github.com/llvm/llvm-project/commit/488c772920566354075f7933eedbe4358c128bd2.diff
LOG: 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.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/CodeGen/CodeGenFunction.cpp
clang/test/CodeGen/attr-naked.c
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 373d4156cd797..720fff759c4ec 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index de717439918d7..15719d12eafeb 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -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;
-
- // 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();
+ // 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();
- 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)
diff --git a/clang/test/CodeGen/attr-naked.c b/clang/test/CodeGen/attr-naked.c
index 2bd9e4c77c025..b4da372247929 100644
--- a/clang/test/CodeGen/attr-naked.c
+++ b/clang/test/CodeGen/attr-naked.c
@@ -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{{.*}} }
More information about the cfe-commits
mailing list