[clang] 6081ccf - Apply function attributes through array declarators

Momchil Velikov via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 23 04:03:24 PDT 2020


Author: Momchil Velikov
Date: 2020-03-23T11:03:13Z
New Revision: 6081ccf4a3b6289717c8ae558ac210c36ddcbfbe

URL: https://github.com/llvm/llvm-project/commit/6081ccf4a3b6289717c8ae558ac210c36ddcbfbe
DIFF: https://github.com/llvm/llvm-project/commit/6081ccf4a3b6289717c8ae558ac210c36ddcbfbe.diff

LOG: Apply function attributes through array declarators

There's inconsistency in handling array types between the
`distributeFunctionTypeAttrXXX` functions and the
`FunctionTypeUnwrapper` in `SemaType.cpp`.

This patch lets `FunctionTypeUnwrapper` apply function type attributes
through array types.

Differential Revision: https://reviews.llvm.org/D75109

Added: 
    clang/test/CodeGen/attr-noreturn.c

Modified: 
    clang/lib/Sema/SemaType.cpp
    clang/test/Sema/attr-noreturn.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 534178388048..356b51e439a6 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6502,6 +6502,7 @@ namespace {
       Desugar,
       Attributed,
       Parens,
+      Array,
       Pointer,
       BlockPointer,
       Reference,
@@ -6522,6 +6523,10 @@ namespace {
         } else if (isa<ParenType>(Ty)) {
           T = cast<ParenType>(Ty)->getInnerType();
           Stack.push_back(Parens);
+        } else if (isa<ConstantArrayType>(Ty) || isa<VariableArrayType>(Ty) ||
+                   isa<IncompleteArrayType>(Ty)) {
+          T = cast<ArrayType>(Ty)->getElementType();
+          Stack.push_back(Array);
         } else if (isa<PointerType>(Ty)) {
           T = cast<PointerType>(Ty)->getPointeeType();
           Stack.push_back(Pointer);
@@ -6599,6 +6604,27 @@ namespace {
       case MacroQualified:
         return wrap(C, cast<MacroQualifiedType>(Old)->getUnderlyingType(), I);
 
+      case Array: {
+        if (const auto *CAT = dyn_cast<ConstantArrayType>(Old)) {
+          QualType New = wrap(C, CAT->getElementType(), I);
+          return C.getConstantArrayType(New, CAT->getSize(), CAT->getSizeExpr(),
+                                        CAT->getSizeModifier(),
+                                        CAT->getIndexTypeCVRQualifiers());
+        }
+
+        if (const auto *VAT = dyn_cast<VariableArrayType>(Old)) {
+          QualType New = wrap(C, VAT->getElementType(), I);
+          return C.getVariableArrayType(
+              New, VAT->getSizeExpr(), VAT->getSizeModifier(),
+              VAT->getIndexTypeCVRQualifiers(), VAT->getBracketsRange());
+        }
+
+        const auto *IAT = cast<IncompleteArrayType>(Old);
+        QualType New = wrap(C, IAT->getElementType(), I);
+        return C.getIncompleteArrayType(New, IAT->getSizeModifier(),
+                                        IAT->getIndexTypeCVRQualifiers());
+      }
+
       case Pointer: {
         QualType New = wrap(C, cast<PointerType>(Old)->getPointeeType(), I);
         return C.getPointerType(New);

diff  --git a/clang/test/CodeGen/attr-noreturn.c b/clang/test/CodeGen/attr-noreturn.c
new file mode 100644
index 000000000000..b420edfc0595
--- /dev/null
+++ b/clang/test/CodeGen/attr-noreturn.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -S -emit-llvm %s -o - | FileCheck %s
+
+typedef void (*fptrs_t[4])(void);
+fptrs_t p __attribute__((noreturn));
+
+void __attribute__((noreturn)) f() {
+  p[0]();
+}
+// CHECK: call
+// CHECK-NEXT: unreachable

diff  --git a/clang/test/Sema/attr-noreturn.c b/clang/test/Sema/attr-noreturn.c
index dab571064a22..3d1e8d7f4079 100644
--- a/clang/test/Sema/attr-noreturn.c
+++ b/clang/test/Sema/attr-noreturn.c
@@ -42,3 +42,34 @@ __attribute__((noreturn)) void f(__attribute__((noreturn)) void (*x)(void)) {
 }
 
 typedef void (*Fun)(void) __attribute__ ((noreturn(2))); // expected-error {{'noreturn' attribute takes no arguments}}
+
+
+typedef void fn_t(void);
+
+fn_t *fp __attribute__((noreturn));
+void __attribute__((noreturn)) f6(int i) {
+  fp();
+}
+
+fn_t *fps[4] __attribute__((noreturn));
+void __attribute__((noreturn)) f7(int i) {
+  fps[i]();
+}
+
+extern fn_t *ifps[] __attribute__((noreturn));
+void __attribute__((noreturn)) f8(int i) {
+  ifps[i]();
+}
+
+void __attribute__((noreturn)) f9(int n) {
+  extern int g9(int, fn_t **);
+  fn_t *fp[n] __attribute__((noreturn));
+  int i = g9(n, fp);
+  fp[i]();
+}
+
+typedef fn_t *fptrs_t[4];
+fptrs_t ps __attribute__((noreturn));
+void __attribute__((noreturn)) f10(int i) {
+  ps[i]();
+}


        


More information about the cfe-commits mailing list