[cfe-commits] r77377 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp test/Sema/block-return-1.c test/Sema/block-return-2.c test/Sema/block-return-3.c

Mike Stump mrs at apple.com
Tue Jul 28 15:04:01 PDT 2009


Author: mrs
Date: Tue Jul 28 17:04:01 2009
New Revision: 77377

URL: http://llvm.org/viewvc/llvm-project?rev=77377&view=rev
Log:
Add noreturn support for blocks.

Added:
    cfe/trunk/test/Sema/block-return-1.c
    cfe/trunk/test/Sema/block-return-2.c
    cfe/trunk/test/Sema/block-return-3.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=77377&r1=77376&r2=77377&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jul 28 17:04:01 2009
@@ -110,6 +110,10 @@
 def warn_falloff_nonvoid_function : Warning<
   "control reaches end of non-void function">,
   InGroup<ReturnType>;
+def err_maybe_falloff_nonvoid_block : Error<
+  "control may reach end of non-void block">;
+def err_falloff_nonvoid_block : Error<
+  "control reaches end of non-void block">;
 
 /// Built-in functions.
 def ext_implicit_lib_function_decl : ExtWarn<

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=77377&r1=77376&r2=77377&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jul 28 17:04:01 2009
@@ -802,8 +802,9 @@
                                       SourceLocation MemberLoc,
                                       IdentifierInfo &Member);
                
-  /// Helpers for dealing with functions.
+  /// Helpers for dealing with blocks and functions.
   void CheckFallThroughForFunctionDef(Decl *D, Stmt *Body);
+  void CheckFallThroughForBlock(QualType BlockTy, Stmt *Body);
   bool CheckParmsForFunctionDef(FunctionDecl *FD);
   void CheckCXXDefaultArguments(FunctionDecl *FD);
   void CheckExtraCXXDefaultArguments(Declarator &D);

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Jul 28 17:04:01 2009
@@ -1124,8 +1124,8 @@
 
 /// CheckFallThroughForFunctionDef - Check that we don't fall off the end of a
 /// function that should return a value.  Check that we don't fall off the end
-/// of a noreturn function.  We assume that functions not marked noreturn will
-/// return.
+/// of a noreturn function.  We assume that functions and blocks not marked
+/// noreturn will return.
 void Sema::CheckFallThroughForFunctionDef(Decl *D, Stmt *Body) {
   // FIXME: Would be nice if we had a better way to control cascading errors,
   // but for now, avoid them.  The problem is that when Parse sees:
@@ -1175,6 +1175,51 @@
   }
 }
 
+/// CheckFallThroughForBlock - Check that we don't fall off the end of a block
+/// that should return a value.  Check that we don't fall off the end of a
+/// noreturn block.  We assume that functions and blocks not marked noreturn
+/// will return.
+void Sema::CheckFallThroughForBlock(QualType BlockTy, Stmt *Body) {
+  // FIXME: Would be nice if we had a better way to control cascading errors,
+  // but for now, avoid them.  The problem is that when Parse sees:
+  //   int foo() { return a; }
+  // The return is eaten and the Sema code sees just:
+  //   int foo() { }
+  // which this code would then warn about.
+  if (getDiagnostics().hasErrorOccurred())
+    return;
+  bool ReturnsVoid = false;
+  bool HasNoReturn = false;
+  if (const FunctionType *FT = BlockTy->getPointeeType()->getAsFunctionType()) {
+    if (FT->getResultType()->isVoidType())
+      ReturnsVoid = true;
+    if (FT->getNoReturnAttr())
+      HasNoReturn = true;
+  }
+    
+  if (ReturnsVoid && !HasNoReturn)
+    return;
+  // FIXME: Funtion try block
+  if (CompoundStmt *Compound = dyn_cast<CompoundStmt>(Body)) {
+    switch (CheckFallThrough(Body)) {
+    case MaybeFallThrough:
+      if (HasNoReturn)
+        Diag(Compound->getRBracLoc(), diag::err_noreturn_block_has_return_expr);
+      else if (!ReturnsVoid)
+        Diag(Compound->getRBracLoc(), diag::err_maybe_falloff_nonvoid_block);
+      break;
+    case AlwaysFallThrough:
+      if (HasNoReturn)
+        Diag(Compound->getRBracLoc(), diag::err_noreturn_block_has_return_expr);
+      else if (!ReturnsVoid)
+        Diag(Compound->getRBracLoc(), diag::err_falloff_nonvoid_block);
+      break;
+    case NeverFallThrough:
+      break;
+    }
+  }
+}
+
 /// CheckParmsForFunctionDef - Check that the parameters of the given
 /// function are appropriate for the definition of a function. This
 /// takes care of any checks that cannot be performed on the

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jul 28 17:04:01 2009
@@ -5490,12 +5490,15 @@
   for (unsigned i = 0, e = BSI->Params.size(); i != e; ++i)
     ArgTypes.push_back(BSI->Params[i]->getType());
 
+  bool NoReturn = BSI->TheDecl->getAttr<NoReturnAttr>();
   QualType BlockTy;
   if (!BSI->hasPrototype)
-    BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0);
+    BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0,
+                                      NoReturn);
   else
     BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(),
-                                      BSI->isVariadic, 0);
+                                      BSI->isVariadic, 0, false, false, 0, 0,
+                                      NoReturn);
 
   // FIXME: Check that return/parameter types are complete/non-abstract
   DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end());
@@ -5507,6 +5510,7 @@
   CurFunctionNeedsScopeChecking = BSI->SavedFunctionNeedsScopeChecking;
   
   BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+  CheckFallThroughForBlock(BlockTy, BSI->TheDecl->getBody());
   return Owned(new (Context) BlockExpr(BSI->TheDecl, BlockTy,
                                        BSI->hasBlockDeclRefExprs));
 }

Added: cfe/trunk/test/Sema/block-return-1.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return-1.c?rev=77377&view=auto

==============================================================================
--- cfe/trunk/test/Sema/block-return-1.c (added)
+++ cfe/trunk/test/Sema/block-return-1.c Tue Jul 28 17:04:01 2009
@@ -0,0 +1,6 @@
+// RUN: clang-cc -fsyntax-only %s -verify -fblocks
+
+int j;
+void foo() {
+  ^ (void) { if (j) return 1; }(); // expected-error {{control may reach end of non-void block}}
+}

Added: cfe/trunk/test/Sema/block-return-2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return-2.c?rev=77377&view=auto

==============================================================================
--- cfe/trunk/test/Sema/block-return-2.c (added)
+++ cfe/trunk/test/Sema/block-return-2.c Tue Jul 28 17:04:01 2009
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only %s -verify -fblocks
+
+void foo() {
+  ^ (void) __attribute__((noreturn)) { }(); // expected-error {{block declared 'noreturn' should not return}}
+}

Added: cfe/trunk/test/Sema/block-return-3.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/block-return-3.c?rev=77377&view=auto

==============================================================================
--- cfe/trunk/test/Sema/block-return-3.c (added)
+++ cfe/trunk/test/Sema/block-return-3.c Tue Jul 28 17:04:01 2009
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only %s -verify -fblocks
+
+void foo() {
+  ^ int (void) { }(); // expected-error {{control reaches end of non-void block}}
+}





More information about the cfe-commits mailing list