[cfe-commits] r77089 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/Analysis/CFG.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaType.cpp test/CodeGen/array.c test/Sema/return.c

Mike Stump mrs at apple.com
Sat Jul 25 14:26:54 PDT 2009


Author: mrs
Date: Sat Jul 25 16:26:53 2009
New Revision: 77089

URL: http://llvm.org/viewvc/llvm-project?rev=77089&view=rev
Log:
Add noreturn as a type attribute, handle printing for them and handle
calls to noreturn function pointers when CFG building.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/Analysis/CFG.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/CodeGen/array.c
    cfe/trunk/test/Sema/return.c

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Jul 25 16:26:53 2009
@@ -135,7 +135,7 @@
   /// Since so few decls have attrs, we keep them in a hash map instead of
   /// wasting space in the Decl class.
   llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
-  
+
   /// \brief Keeps track of the static data member templates from which
   /// static data members of class template specializations were instantiated.
   ///
@@ -218,7 +218,7 @@
   
   /// \brief Erase the attributes corresponding to the given declaration.
   void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
-  
+
   /// \brief If this variable is an instantiated static data member of a
   /// class template specialization, returns the templated static data member 
   /// from which it was instantiated.
@@ -287,6 +287,10 @@
   /// from T and the gc attribute.
   QualType getObjCGCQualType(QualType T, QualType::GCAttrTypes gcAttr);
   
+  /// getNoReturnType - Add the noreturn attribute to the given type which must
+  /// be a FunctionType or a pointer to an allowable type or a BlockPointer.
+  QualType getNoReturnType(QualType T);
+  
   /// getComplexType - Return the uniqued reference to the type for a complex
   /// number with the specified element type.
   QualType getComplexType(QualType T);
@@ -375,7 +379,7 @@
 
   /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
   ///
-  QualType getFunctionNoProtoType(QualType ResultTy);
+  QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false);
 
   /// getFunctionType - Return a normal function type with a typed argument
   /// list.  isVariadic indicates whether the argument list includes '...'.
@@ -383,7 +387,8 @@
                            unsigned NumArgs, bool isVariadic,
                            unsigned TypeQuals, bool hasExceptionSpec = false,
                            bool hasAnyExceptionSpec = false,
-                           unsigned NumExs = 0, const QualType *ExArray = 0);
+                           unsigned NumExs = 0, const QualType *ExArray = 0,
+                           bool NoReturn = false);
 
   /// getTypeDeclType - Return the unique reference to the type for
   /// the specified type declaration.

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Jul 25 16:26:53 2009
@@ -215,6 +215,9 @@
   bool isObjCGCStrong() const {
     return getObjCGCAttr() == Strong;
   }
+
+  /// getNoReturnAttr() - Return the noreturn attribute of this type.
+  bool getNoReturnAttr() const;
 };
 
 } // end clang.
@@ -545,7 +548,7 @@
   Type *getBaseType() const { return BaseType; }
   QualType::GCAttrTypes getObjCGCAttr() const { return GCAttrType; }
   unsigned getAddressSpace() const { return AddressSpace; }
-  
+
   virtual void getAsStringInternal(std::string &InnerString, 
                                    const PrintingPolicy &Policy) const;
   
@@ -1344,19 +1347,25 @@
   /// cv-qualifier-seq, [...], are part of the function type.
   ///
   unsigned TypeQuals : 3;
+
+  /// NoReturn - Indicates if the function type is attribute noreturn.
+  unsigned NoReturn : 1;
   
   // The type returned by the function.
   QualType ResultType;
 protected:
   FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
-               unsigned typeQuals, QualType Canonical, bool Dependent)
+               unsigned typeQuals, QualType Canonical, bool Dependent,
+               bool noReturn = false)
     : Type(tc, Canonical, Dependent),
-      SubClassData(SubclassInfo), TypeQuals(typeQuals), ResultType(res) {}
+      SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn),
+      ResultType(res) {}
   bool getSubClassData() const { return SubClassData; }
   unsigned getTypeQuals() const { return TypeQuals; }
 public:
   
   QualType getResultType() const { return ResultType; }
+  bool getNoReturnAttr() const { return NoReturn; }
 
   
   static bool classof(const Type *T) {
@@ -1369,9 +1378,10 @@
 /// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has
 /// no information available about its arguments.
 class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
-  FunctionNoProtoType(QualType Result, QualType Canonical)
+  FunctionNoProtoType(QualType Result, QualType Canonical,
+                      bool NoReturn = false)
     : FunctionType(FunctionNoProto, Result, false, 0, Canonical, 
-                   /*Dependent=*/false) {}
+                   /*Dependent=*/false, NoReturn) {}
   friend class ASTContext;  // ASTContext creates these.
 public:
   // No additional state past what FunctionType provides.
@@ -1380,9 +1390,11 @@
                                    const PrintingPolicy &Policy) const;
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getResultType());
+    Profile(ID, getResultType(), getNoReturnAttr());
   }
-  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) {
+  static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
+                      bool NoReturn) {
+    ID.AddInteger(NoReturn);
     ID.AddPointer(ResultType.getAsOpaquePtr());
   }
   
@@ -1411,10 +1423,10 @@
   FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
                     bool isVariadic, unsigned typeQuals, bool hasExs,
                     bool hasAnyExs, const QualType *ExArray,
-                    unsigned numExs, QualType Canonical)
+                    unsigned numExs, QualType Canonical, bool NoReturn)
     : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
                    (Result->isDependentType() || 
-                    hasAnyDependentType(ArgArray, numArgs))),
+                    hasAnyDependentType(ArgArray, numArgs)), NoReturn),
       NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
       AnyExceptionSpec(hasAnyExs) {
     // Fill in the trailing argument array.
@@ -1497,7 +1509,8 @@
                       arg_type_iterator ArgTys, unsigned NumArgs,
                       bool isVariadic, unsigned TypeQuals,
                       bool hasExceptionSpec, bool anyExceptionSpec,
-                      unsigned NumExceptions, exception_iterator Exs);
+                      unsigned NumExceptions, exception_iterator Exs,
+                      bool NoReturn);
 };
 
 
@@ -2068,6 +2081,18 @@
     return PT->getPointeeType().getObjCGCAttr(); 
   return GCNone;
 }
+
+/// getNoReturnAttr - Return the noreturn attribute of this type.
+inline bool QualType::getNoReturnAttr() const {
+  QualType CT = getTypePtr()->getCanonicalTypeInternal();
+  if (const PointerType *PT = getTypePtr()->getAsPointerType()) {
+    if (const FunctionType *FT = PT->getPointeeType()->getAsFunctionType())
+      return FT->getNoReturnAttr();
+  } else if (const FunctionType *FT = getTypePtr()->getAsFunctionType())
+    return FT->getNoReturnAttr();
+
+  return false;
+}
   
 /// isMoreQualifiedThan - Determine whether this type is more
 /// qualified than the Other type. For example, "const volatile int"

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Jul 25 16:26:53 2009
@@ -965,7 +965,7 @@
   
   // Check if we've already instantiated this type.
   llvm::FoldingSetNodeID ID;
-  ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);      
+  ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);
   void *InsertPos = 0;
   if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(EXTQy, CVRQuals);
@@ -1007,17 +1007,17 @@
   unsigned AddressSpace = 0;
   
   if (ExtQualType *EQT = dyn_cast<ExtQualType>(TypeNode)) {
-    // If this type already has an address space specified, it cannot get
+    // If this type already has an ObjCGC specified, it cannot get
     // another one.
     assert(EQT->getObjCGCAttr() == QualType::GCNone &&
-           "Type cannot be in multiple addr spaces!");
+           "Type cannot have multiple ObjCGCs!");
     AddressSpace = EQT->getAddressSpace();
     TypeNode = EQT->getBaseType();
   }
   
   // Check if we've already instantiated an gc qual'd type of this type.
   llvm::FoldingSetNodeID ID;
-  ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);      
+  ExtQualType::Profile(ID, TypeNode, AddressSpace, GCAttr);
   void *InsertPos = 0;
   if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(EXTQy, CVRQuals);
@@ -1041,6 +1041,30 @@
   return QualType(New, CVRQuals);
 }
 
+QualType ASTContext::getNoReturnType(QualType T) {
+  if (T->isPointerType()) {
+    QualType Pointee = T->getAsPointerType()->getPointeeType();
+    QualType ResultType = getNoReturnType(Pointee);
+    return getPointerType(ResultType);
+  }
+  if (T->isBlockPointerType()) {
+    QualType Pointee = T->getAsBlockPointerType()->getPointeeType();
+    QualType ResultType = getNoReturnType(Pointee);
+    return getBlockPointerType(ResultType);
+  }    
+  if (!T->isFunctionType())
+    assert(0 && "can't noreturn qualify non-pointer to function or block type");
+  
+  if (const FunctionNoProtoType *F = dyn_cast<FunctionNoProtoType>(T)) {
+    return getFunctionNoProtoType(F->getResultType(), true);
+  }
+  const FunctionProtoType *F = cast<FunctionProtoType>(T);
+  return getFunctionType(F->getResultType(), F->arg_type_begin(),
+                         F->getNumArgs(), F->isVariadic(), F->getTypeQuals(),
+                         F->hasExceptionSpec(), F->hasAnyExceptionSpec(),
+                         F->getNumExceptions(), F->exception_begin(), true);
+}
+
 /// getComplexType - Return the uniqued reference to the type for a complex
 /// number with the specified element type.
 QualType ASTContext::getComplexType(QualType T) {
@@ -1474,11 +1498,11 @@
 
 /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
 ///
-QualType ASTContext::getFunctionNoProtoType(QualType ResultTy) {
+QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn) {
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
   llvm::FoldingSetNodeID ID;
-  FunctionNoProtoType::Profile(ID, ResultTy);
+  FunctionNoProtoType::Profile(ID, ResultTy, NoReturn);
   
   void *InsertPos = 0;
   if (FunctionNoProtoType *FT = 
@@ -1487,7 +1511,7 @@
   
   QualType Canonical;
   if (!ResultTy->isCanonical()) {
-    Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy));
+    Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn);
     
     // Get the new insert position for the node we care about.
     FunctionNoProtoType *NewIP =
@@ -1495,7 +1519,8 @@
     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
   }
   
-  FunctionNoProtoType *New =new(*this,8)FunctionNoProtoType(ResultTy,Canonical);
+  FunctionNoProtoType *New
+    = new (*this,8) FunctionNoProtoType(ResultTy, Canonical, NoReturn);
   Types.push_back(New);
   FunctionNoProtoTypes.InsertNode(New, InsertPos);
   return QualType(New, 0);
@@ -1507,13 +1532,13 @@
                                      unsigned NumArgs, bool isVariadic,
                                      unsigned TypeQuals, bool hasExceptionSpec,
                                      bool hasAnyExceptionSpec, unsigned NumExs,
-                                     const QualType *ExArray) {
+                                     const QualType *ExArray, bool NoReturn) {
   // Unique functions, to guarantee there is only one function of a particular
   // structure.
   llvm::FoldingSetNodeID ID;
   FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic,
                              TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
-                             NumExs, ExArray);
+                             NumExs, ExArray, NoReturn);
 
   void *InsertPos = 0;
   if (FunctionProtoType *FTP = 
@@ -1539,7 +1564,7 @@
 
     Canonical = getFunctionType(getCanonicalType(ResultTy),
                                 CanonicalArgs.data(), NumArgs,
-                                isVariadic, TypeQuals);
+                                isVariadic, TypeQuals, NoReturn);
 
     // Get the new insert position for the node we care about.
     FunctionProtoType *NewIP =
@@ -1556,7 +1581,7 @@
                                  NumExs*sizeof(QualType), 8);
   new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic,
                               TypeQuals, hasExceptionSpec, hasAnyExceptionSpec,
-                              ExArray, NumExs, Canonical);
+                              ExArray, NumExs, Canonical, NoReturn);
   Types.push_back(FTP);
   FunctionProtoTypes.InsertNode(FTP, InsertPos);
   return QualType(FTP, 0);
@@ -3344,7 +3369,12 @@
     allLTypes = false;
   if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType()))
     allRTypes = false;
-
+  bool NoReturn = lbase->getNoReturnAttr() || rbase->getNoReturnAttr();
+  if (NoReturn != lbase->getNoReturnAttr())
+    allLTypes = false;
+  if (NoReturn != rbase->getNoReturnAttr())
+    allRTypes = false;
+    
   if (lproto && rproto) { // two C99 style function prototypes
     assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
            "C++ shouldn't be here");
@@ -3378,7 +3408,8 @@
     if (allLTypes) return lhs;
     if (allRTypes) return rhs;
     return getFunctionType(retType, types.begin(), types.size(),
-                           lproto->isVariadic(), lproto->getTypeQuals());
+                           lproto->isVariadic(), lproto->getTypeQuals(),
+                           NoReturn);
   }
 
   if (lproto) allRTypes = false;
@@ -3405,12 +3436,12 @@
     if (allRTypes) return rhs;
     return getFunctionType(retType, proto->arg_type_begin(),
                            proto->getNumArgs(), lproto->isVariadic(),
-                           lproto->getTypeQuals());
+                           lproto->getTypeQuals(), NoReturn);
   }
 
   if (allLTypes) return lhs;
   if (allRTypes) return rhs;
-  return getFunctionNoProtoType(retType);
+  return getFunctionNoProtoType(retType, NoReturn);
 }
 
 QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) {

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat Jul 25 16:26:53 2009
@@ -904,7 +904,7 @@
                                 unsigned NumArgs, bool isVariadic,
                                 unsigned TypeQuals, bool hasExceptionSpec,
                                 bool anyExceptionSpec, unsigned NumExceptions,
-                                exception_iterator Exs) {
+                                exception_iterator Exs, bool NoReturn) {
   ID.AddPointer(Result.getAsOpaquePtr());
   for (unsigned i = 0; i != NumArgs; ++i)
     ID.AddPointer(ArgTys[i].getAsOpaquePtr());
@@ -916,12 +916,13 @@
     for(unsigned i = 0; i != NumExceptions; ++i)
       ID.AddPointer(Exs[i].getAsOpaquePtr());
   }
+  ID.AddInteger(NoReturn);
 }
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) {
   Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(),
           getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(),
-          getNumExceptions(), exception_begin());
+          getNumExceptions(), exception_begin(), getNoReturnAttr());
 }
 
 void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
@@ -1082,7 +1083,7 @@
     if (EQT->getObjCGCAttr())
       GCAttrType = EQT->getObjCGCAttr();
     return EQT->getBaseType();
-  }else {
+  } else {
     // Use the sugared type unless desugaring found extra qualifiers.
     return (DT.getCVRQualifiers() ? DT.getTypePtr() : T);
   }
@@ -1413,6 +1414,8 @@
     S = "(" + S + ")";
   
   S += "()";
+  if (getNoReturnAttr())
+    S += " __attribute__((noreturn))";
   getResultType().getAsStringInternal(S, Policy);
 }
 
@@ -1442,6 +1445,8 @@
   }
   
   S += ")";
+  if (getNoReturnAttr())
+    S += " __attribute__((noreturn))";
   getResultType().getAsStringInternal(S, Policy);
 }
 

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Sat Jul 25 16:26:53 2009
@@ -501,25 +501,29 @@
   
 CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, bool alwaysAdd) {
   // If this is a call to a no-return function, this stops the block here.
-  if (FunctionDecl *FD = C->getDirectCallee()) {
-    
-    if (!FD->hasAttr<NoReturnAttr>())
-      return VisitStmt(C, alwaysAdd);
-    
-    if (Block && !FinishBlock(Block))
-      return 0;
-    
-    // Create new block with no successor for the remaining pieces.
-    Block = createBlock(false);
-    Block->appendStmt(C);
+  bool NoReturn = false;
+  if (C->getCallee()->getType().getNoReturnAttr()) {
+    NoReturn = true;
+  }
+
+  if (FunctionDecl *FD = C->getDirectCallee())
+    if (FD->hasAttr<NoReturnAttr>())
+      NoReturn = true;
+
+  if (!NoReturn)
+    return VisitStmt(C, alwaysAdd);
     
-    // Wire this to the exit block directly.
-    Block->addSuccessor(&cfg->getExit());
+  if (Block && !FinishBlock(Block))
+    return 0;
     
-    return VisitChildren(C);
-  }
+  // Create new block with no successor for the remaining pieces.
+  Block = createBlock(false);
+  Block->appendStmt(C);
+
+  // Wire this to the exit block directly.
+  Block->addSuccessor(&cfg->getExit());
   
-  return VisitStmt(C, alwaysAdd);
+  return VisitChildren(C);
 }
 
 CFGBlock *CFGBuilder::VisitChooseExpr(ChooseExpr *C) {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sat Jul 25 16:26:53 2009
@@ -1084,7 +1084,10 @@
     bool NoReturnEdge = false;
     if (CallExpr *C = dyn_cast<CallExpr>(S)) {
       Expr *CEE = C->getCallee()->IgnoreParenCasts();
-      if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
+      if (CEE->getType().getNoReturnAttr()) {
+        NoReturnEdge = true;
+        HasFakeEdge = true;
+      } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CEE)) {
         if (FunctionDecl *FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
           if (FD->hasAttr<NoReturnAttr>()) {
             NoReturnEdge = true;

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat Jul 25 16:26:53 2009
@@ -1506,6 +1506,22 @@
   Type = S.Context.getObjCGCQualType(Type, GCAttr);
 }
 
+/// HandleNoReturnTypeAttribute - Process the noreturn attribute on the
+/// specified type.  The attribute contains 0 arguments.
+static void HandleNoReturnTypeAttribute(QualType &Type, 
+                                        const AttributeList &Attr, Sema &S) {
+  if (Attr.getNumArgs() != 0)
+    return;
+
+  // We only apply this to a pointer to function or a pointer to block.
+  if (!Type->isFunctionPointerType()
+      && !Type->isBlockPointerType()
+      && !Type->isFunctionType())
+    return;
+
+  Type = S.Context.getNoReturnType(Type);
+}
+
 void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
   // Scan through and apply attributes to this type where it makes sense.  Some
   // attributes (such as __address_space__, __vector_size__, etc) apply to the
@@ -1522,6 +1538,9 @@
     case AttributeList::AT_objc_gc:
       HandleObjCGCTypeAttribute(Result, *AL, *this);
       break;
+    case AttributeList::AT_noreturn:
+      HandleNoReturnTypeAttribute(Result, *AL, *this);
+      break;
     }
   }
 }

Modified: cfe/trunk/test/CodeGen/array.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/array.c?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/array.c (original)
+++ cfe/trunk/test/CodeGen/array.c Sat Jul 25 16:26:53 2009
@@ -1,11 +1,11 @@
 // RUN: clang-cc -emit-llvm %s -o %t
 
-int f() {
+void f() {
  int a[2];
  a[0] = 0;
 }
 
-int f2() {
+void f2() {
   int x = 0;
   int y = 1;
   int a[10] = { y, x, 2, 3};

Modified: cfe/trunk/test/Sema/return.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/return.c?rev=77089&r1=77088&r2=77089&view=diff

==============================================================================
--- cfe/trunk/test/Sema/return.c (original)
+++ cfe/trunk/test/Sema/return.c Sat Jul 25 16:26:53 2009
@@ -158,6 +158,7 @@
 } // expected-warning {{control reaches end of non-void function}}
 
 int j;
+void (*fptr)() __attribute__((noreturn));
 int test27() {
   switch (j) {
   case 1:
@@ -178,6 +179,9 @@
   case 5:
     while (1) { return 1; }
     break;
+  case 6:
+    fptr();
+    break;
   default:
     return 1;
   }





More information about the cfe-commits mailing list