[PATCH] Fix to PR15845 - Clang accepts invalid code

Serge Pavlov sepavloff at gmail.com
Sun Apr 28 06:37:51 PDT 2013


Hi all,

This patch fixes PR15845 - Clang accepts invalid code,
http://llvm.org/bugs/show_bug.cgi?id=15845.
Could someone please review this patch?
Thank you.
--Serge

Description:
The problem is that clang in C++ mode accepts the code:
    int foo(xxx);
Clang intentionally accepts this code due to a check in
Parser::ParseImplicitInt, which appeared in r156854.
The comment in the inserted code states that MS supports implicit int in
C++ mode, however it looks like none of VS2005, VS2008, VS2010 or VS2012
does it. So removing the check for MS extension solves the problem.
Another problem - the same code compiled in C mode produces an error, while
both GCC and MSC accept it. To fix it the message
err_ident_list_in_fn_declaration was converted into warning.

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Parse/ParseDecl.cpp
  lib/Sema/SemaType.cpp
  test/Sema/MicrosoftCompatibility.cpp
  test/Sema/alloc_size.c
  test/Sema/function.c
  test/Sema/invalid-decl.c

-----------------------------------------------------------------------------------------------------
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td
b/include/clang/Basic/DiagnosticSemaKinds.td
index 1461716..166dbab 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2314,8 +2314,9 @@ def err_void_only_param : Error<
   "'void' must be the first and only parameter if specified">;
 def err_void_param_qualified : Error<
   "'void' as parameter must not have type qualifiers">;
-def err_ident_list_in_fn_declaration : Error<
-  "a parameter list without types is only allowed in a function
definition">;
+def warn_ident_list_in_fn_declaration : Warning<
+  "a parameter list without types is only allowed in a function
definition">,
+  InGroup<C99Compat>;
 def ext_param_not_declared : Extension<
   "parameter %0 was not declared, defaulting to type 'int'">;
 def err_param_typedef_of_void : Error<
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index d786ce2..2f0c1a3 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2038,10 +2038,9 @@ bool Parser::ParseImplicitInt(DeclSpec &DS,
CXXScopeSpec *SS,
   // error, do lookahead to try to do better recovery. This never applies
   // within a type specifier. Outside of C++, we allow this even if the
   // language doesn't "officially" support implicit int -- we support
-  // implicit int as an extension in C99 and C11. Allegedly, MS also
-  // supports implicit int in C++ mode.
+  // implicit int as an extension in C99 and C11.
   if (DSC != DSC_type_specifier && DSC != DSC_trailing &&
-      (!getLangOpts().CPlusPlus || getLangOpts().MicrosoftExt) &&
+      !getLangOpts().CPlusPlus &&
       isValidAfterIdentifierInDeclarator(NextToken())) {
     // If this token is valid for implicit int, e.g. "static x = 4", then
     // we just avoid eating the identifier, so it will be parsed as the
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 8bf5143..243b772 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2742,7 +2742,7 @@ static TypeSourceInfo
*GetFullTypeForDeclarator(TypeProcessingState &state,
         if (FTI.NumArgs && FTI.ArgInfo[0].Param == 0) {
           // C99 6.7.5.3p3: Reject int(x,y,z) when it's not a function
           // definition.
-          S.Diag(FTI.ArgInfo[0].IdentLoc,
diag::err_ident_list_in_fn_declaration);
+          S.Diag(FTI.ArgInfo[0].IdentLoc,
diag::warn_ident_list_in_fn_declaration);
           D.setInvalidType(true);
           // Recover by creating a K&R-style function type.
           T = Context.getFunctionNoProtoType(T);
diff --git a/test/Sema/MicrosoftCompatibility.cpp
b/test/Sema/MicrosoftCompatibility.cpp
new file mode 100644
index 0000000..15c2558
--- /dev/null
+++ b/test/Sema/MicrosoftCompatibility.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 %s -fsyntax-only -Wno-unused-value -Wmicrosoft -verify
-fms-compatibility
+
+// PR15845
+int foo(xxx); // expected-error{{unknown type name}}
diff --git a/test/Sema/alloc_size.c b/test/Sema/alloc_size.c
index 84f3932..0067bea 100644
--- a/test/Sema/alloc_size.c
+++ b/test/Sema/alloc_size.c
@@ -22,6 +22,6 @@ void *fn8(int, int) __attribute__((alloc_size(1, 1))); //
OK
 void* fn9(unsigned) __attribute__((alloc_size(12345678901234567890123)));
// expected-warning {{integer constant is too large for its type}} //
expected-error {{attribute parameter 1 is out of bounds}}

 void* fn10(size_t, size_t) __attribute__((alloc_size(1,2))); //
expected-error{{redefinition of parameter}} \
-                                                             //
expected-error{{a parameter list without types is only allowed in a
function definition}} \
+                                                             //
expected-warning{{a parameter list without types is only allowed in a
function definition}} \
                                                              //
expected-error{{attribute parameter 1 is out of bounds}}
 void* fn11() __attribute__((alloc_size(1))); // expected-error{{attribute
parameter 1 is out of bounds}}
diff --git a/test/Sema/function.c b/test/Sema/function.c
index bbf81a5..c0125ed 100644
--- a/test/Sema/function.c
+++ b/test/Sema/function.c
@@ -17,7 +17,7 @@ void h();  // expected-note {{previous declaration is
here}}
 void h (const char *fmt, ...) {} // expected-error{{conflicting types for
'h'}}

 // PR1965
-int t5(b);          // expected-error {{parameter list without types}}
+int t5(b);          // expected-warning {{parameter list without types}}
 int t6(int x, g);   // expected-warning {{type specifier missing, defaults
to 'int'}}

 int t7(, );       // expected-error {{expected parameter declarator}}
expected-error {{expected parameter declarator}}
diff --git a/test/Sema/invalid-decl.c b/test/Sema/invalid-decl.c
index 950d51d..30b7657 100644
--- a/test/Sema/invalid-decl.c
+++ b/test/Sema/invalid-decl.c
@@ -40,7 +40,7 @@ void foo() {
 }

 void test2();
-void test2(undef); // expected-error {{a parameter list without types is
only allowed in a function definition}}
+void test2(undef); // expected-warning {{a parameter list without types is
only allowed in a function definition}}
 void test2() { }

 void test3();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130428/b6443240/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Fix-to-PR15845-Clang-accepts-invalid-code.patch
Type: application/octet-stream
Size: 5163 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130428/b6443240/attachment.obj>


More information about the llvm-commits mailing list