Sema: Don't permit variably modified types in typeid
authorDavid Majnemer <david.majnemer@gmail.com>
Fri, 21 Nov 2014 21:09:12 +0000 (21:09 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Fri, 21 Nov 2014 21:09:12 +0000 (21:09 +0000)
GCC and ICC both reject this and the 'Runtime-sized arrays with
automatic storage duration' (N3639) paper forbade this as well.
Previously, we would crash on our way to mangling.

This fixes PR21632.

llvm-svn: 222569

clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/typeid.cpp

index 310a9b2a2ff74f4b1a0aa32f5288683161adf06c..9639b3ce42c12b5ad2273e55fa88d946ec632dc4 100644 (file)
@@ -5303,6 +5303,7 @@ def err_uuidof_without_guid : Error<
 def err_uuidof_with_multiple_guids : Error<
   "cannot call operator __uuidof on a type with multiple GUIDs">;
 def err_incomplete_typeid : Error<"'typeid' of incomplete type %0">;
+def err_variably_modified_typeid : Error<"'typeid' of variably modified type %0">;
 def err_static_illegal_in_new : Error<
   "the 'static' modifier for the array size is not legal in new expressions">;
 def err_array_new_needs_size : Error<
index 93996685105d2c88ef6a68c242b1813f5320e47f..c71a4e93bbd5900993ef14096464e13df6e17877 100644 (file)
@@ -384,6 +384,9 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
       RequireCompleteType(TypeidLoc, T, diag::err_incomplete_typeid))
     return ExprError();
 
+  if (T->isVariablyModifiedType())
+    return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T);
+
   return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), Operand,
                                      SourceRange(TypeidLoc, RParenLoc));
 }
@@ -438,6 +441,10 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
     }
   }
 
+  if (E->getType()->isVariablyModifiedType())
+    return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
+                     << E->getType());
+
   return new (Context) CXXTypeidExpr(TypeInfoType.withConst(), E,
                                      SourceRange(TypeidLoc, RParenLoc));
 }
index d3a2a28deb8b8b4a918aca9b55ee76141c2be4f9..48fcce0b4924f1c615b841466067537fd82ba154 100644 (file)
@@ -21,3 +21,9 @@ void g1(X &x) {
   (void)typeid(X&); // expected-error{{'typeid' of incomplete type 'X'}}
   (void)typeid(x); // expected-error{{'typeid' of incomplete type 'X'}}
 }
+
+void h(int i) {
+  char V[i];
+  typeid(V);        // expected-error{{'typeid' of variably modified type 'char [i]'}}
+  typeid(char [i]); // expected-error{{'typeid' of variably modified type 'char [i]'}}
+}