From bc34b1d7f4f371bfdebf68d66086f54586d68abe Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 11 Apr 2011 00:23:45 +0000 Subject: [PATCH] PR9669: implement correct checking for [dcl.init.string]p2. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129260 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaInit.cpp | 19 ++++++++++++++----- .../dcl.decl/dcl.init/dcl.init.string/p2.cpp | 2 ++ test/SemaCXX/warn-global-constructors.cpp | 4 ++-- 4 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4ec3d735af..1ca042e4a8 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2208,6 +2208,8 @@ def err_excess_initializers_in_char_array_initializer : Error< "excess elements in char array initializer">; def warn_excess_initializers_in_char_array_initializer : ExtWarn< "excess elements in char array initializer">; +def err_initializer_string_for_char_array_too_long : Error< + "initializer-string for char array is too long">; def warn_initializer_string_for_char_array_too_long : ExtWarn< "initializer-string for char array is too long">; def warn_missing_field_initializers : Warning< diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 0f8d4ddc33..1dff64e855 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -92,13 +92,22 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, const ConstantArrayType *CAT = cast(AT); - // C99 6.7.8p14. We have an array of character type with known size. However, + // We have an array of character type with known size. However, // the size may be smaller or larger than the string we are initializing. // FIXME: Avoid truncation for 64-bit length strings. - if (StrLength-1 > CAT->getSize().getZExtValue()) - S.Diag(Str->getSourceRange().getBegin(), - diag::warn_initializer_string_for_char_array_too_long) - << Str->getSourceRange(); + if (S.getLangOptions().CPlusPlus) { + // [dcl.init.string]p2 + if (StrLength > CAT->getSize().getZExtValue()) + S.Diag(Str->getSourceRange().getBegin(), + diag::err_initializer_string_for_char_array_too_long) + << Str->getSourceRange(); + } else { + // C99 6.7.8p14. + if (StrLength-1 > CAT->getSize().getZExtValue()) + S.Diag(Str->getSourceRange().getBegin(), + diag::warn_initializer_string_for_char_array_too_long) + << Str->getSourceRange(); + } // Set the type to the actual size that we are initializing. If we have // something like: diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp new file mode 100644 index 0000000000..3d67fccb42 --- /dev/null +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.string/p2.cpp @@ -0,0 +1,2 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +char test1[1]="f"; // expected-error {{initializer-string for char array is too long}} diff --git a/test/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp index ad609545ec..6330958df7 100644 --- a/test/SemaCXX/warn-global-constructors.cpp +++ b/test/SemaCXX/warn-global-constructors.cpp @@ -53,8 +53,8 @@ namespace test3 { namespace test4 { char a[] = "hello"; - char b[5] = "hello"; - char c[][5] = { "hello" }; + char b[6] = "hello"; + char c[][6] = { "hello" }; } namespace test5 { -- 2.40.0