diff options
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 23 | ||||
-rw-r--r-- | test/SemaCXX/vla.cpp | 5 |
2 files changed, 17 insertions, 11 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index bee542234b..57b0e9d9c5 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5266,21 +5266,22 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, ProcessDeclAttributes(S, NewFD, D, /*NonInheritable=*/true, /*Inheritable=*/false); + // Functions returning a variably modified type violate C99 6.7.5.2p2 + // because all functions have linkage. + if (!NewFD->isInvalidDecl() && + NewFD->getResultType()->isVariablyModifiedType()) { + Diag(NewFD->getLocation(), diag::err_vm_func_decl); + NewFD->setInvalidDecl(); + } + if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. bool isExplicitSpecialization=false; if (!NewFD->isInvalidDecl()) { - if (NewFD->getResultType()->isVariablyModifiedType()) { - // Functions returning a variably modified type violate C99 6.7.5.2p2 - // because all functions have linkage. - Diag(NewFD->getLocation(), diag::err_vm_func_decl); - NewFD->setInvalidDecl(); - } else { - if (NewFD->isMain()) - CheckMain(NewFD, D.getDeclSpec()); - D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, - isExplicitSpecialization)); - } + if (NewFD->isMain()) + CheckMain(NewFD, D.getDeclSpec()); + D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, + isExplicitSpecialization)); } assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || Previous.getResultKind() != LookupResult::FoundOverloaded) && diff --git a/test/SemaCXX/vla.cpp b/test/SemaCXX/vla.cpp new file mode 100644 index 0000000000..d63b6335f4 --- /dev/null +++ b/test/SemaCXX/vla.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -verify %s + +// PR11925 +int n; +int (&f())[n]; // expected-error {{function declaration cannot have variably modified type}} |