[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