aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td5
-rw-r--r--lib/Lex/PPExpressions.cpp13
-rw-r--r--lib/Sema/SemaExpr.cpp14
-rw-r--r--lib/Sema/SemaType.cpp28
-rw-r--r--test/Lexer/long-long.cpp22
-rw-r--r--test/Sema/c89-2.c5
-rw-r--r--test/Sema/c89.c6
-rw-r--r--test/SemaCXX/constant-expression.cpp2
-rw-r--r--test/SemaCXX/cxx98-compat-pedantic.cpp6
9 files changed, 75 insertions, 26 deletions
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index f85928740b..999c6d2618 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -78,9 +78,12 @@ def note_decl_hiding_tag_type : Note<
"%1 %0 is hidden by a non-type declaration of %0 here">;
// Sema && Lex
-def ext_longlong : Extension<
+def ext_c99_longlong : Extension<
"'long long' is an extension when C99 mode is not enabled">,
InGroup<LongLong>;
+def ext_cxx11_longlong : Extension<
+ "'long long' is a C++11 extension">,
+ InGroup<CXX11>;
def warn_cxx98_compat_longlong : Warning<
"'long long' is incompatible with C++98">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index f5984f58bf..d5a88db470 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -220,10 +220,15 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
if (Literal.hasUDSuffix())
PP.Diag(PeekTok, diag::err_pp_invalid_udl) << /*integer*/1;
- // long long is a C99 feature.
- if (!PP.getLangOpts().C99 && Literal.isLongLong)
- PP.Diag(PeekTok, PP.getLangOpts().CPlusPlus0x ?
- diag::warn_cxx98_compat_longlong : diag::ext_longlong);
+ // 'long long' is a C99 or C++11 feature.
+ if (!PP.getLangOpts().C99 && Literal.isLongLong) {
+ if (PP.getLangOpts().CPlusPlus)
+ PP.Diag(PeekTok,
+ PP.getLangOpts().CPlusPlus0x ?
+ diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
+ else
+ PP.Diag(PeekTok, diag::ext_c99_longlong);
+ }
// Parse the integer literal into Result.
if (Literal.GetIntegerValue(Result.Val)) {
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index b864a2e8a0..41985328bb 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2777,11 +2777,15 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
} else {
QualType Ty;
- // long long is a C99 feature.
- if (!getLangOpts().C99 && Literal.isLongLong)
- Diag(Tok.getLocation(),
- getLangOpts().CPlusPlus0x ?
- diag::warn_cxx98_compat_longlong : diag::ext_longlong);
+ // 'long long' is a C99 or C++11 feature.
+ if (!getLangOpts().C99 && Literal.isLongLong) {
+ if (getLangOpts().CPlusPlus)
+ Diag(Tok.getLocation(),
+ getLangOpts().CPlusPlus0x ?
+ diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
+ else
+ Diag(Tok.getLocation(), diag::ext_c99_longlong);
+ }
// Get the value in the widest-possible width.
unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth();
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index b5328144bb..243ae12d2a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -698,11 +698,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
case DeclSpec::TSW_longlong:
Result = Context.LongLongTy;
- // long long is a C99 feature.
- if (!S.getLangOpts().C99)
- S.Diag(DS.getTypeSpecWidthLoc(),
- S.getLangOpts().CPlusPlus0x ?
- diag::warn_cxx98_compat_longlong : diag::ext_longlong);
+ // 'long long' is a C99 or C++11 feature.
+ if (!S.getLangOpts().C99) {
+ if (S.getLangOpts().CPlusPlus)
+ S.Diag(DS.getTypeSpecWidthLoc(),
+ S.getLangOpts().CPlusPlus0x ?
+ diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
+ else
+ S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong);
+ }
break;
}
} else {
@@ -713,11 +717,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
case DeclSpec::TSW_longlong:
Result = Context.UnsignedLongLongTy;
- // long long is a C99 feature.
- if (!S.getLangOpts().C99)
- S.Diag(DS.getTypeSpecWidthLoc(),
- S.getLangOpts().CPlusPlus0x ?
- diag::warn_cxx98_compat_longlong : diag::ext_longlong);
+ // 'long long' is a C99 or C++11 feature.
+ if (!S.getLangOpts().C99) {
+ if (S.getLangOpts().CPlusPlus)
+ S.Diag(DS.getTypeSpecWidthLoc(),
+ S.getLangOpts().CPlusPlus0x ?
+ diag::warn_cxx98_compat_longlong : diag::ext_cxx11_longlong);
+ else
+ S.Diag(DS.getTypeSpecWidthLoc(), diag::ext_c99_longlong);
+ }
break;
}
}
diff --git a/test/Lexer/long-long.cpp b/test/Lexer/long-long.cpp
new file mode 100644
index 0000000000..c3f371d17f
--- /dev/null
+++ b/test/Lexer/long-long.cpp
@@ -0,0 +1,22 @@
+/* RUN: %clang_cc1 -x c -std=c89 -fsyntax-only -verify -pedantic-errors -Wno-empty-translation-unit %s
+ * RUN: %clang_cc1 -x c -std=c99 -fsyntax-only -verify -pedantic-errors -Wno-empty-translation-unit %s
+ * RUN: %clang_cc1 -x c++ -std=c++98 -fsyntax-only -verify -pedantic-errors -Wno-empty-translation-unit %s
+ * RUN: %clang_cc1 -x c++ -std=c++11 -fsyntax-only -verify -Wc++98-compat-pedantic -Wno-empty-translation-unit %s
+ */
+
+#if !defined(__cplusplus)
+# if __STDC_VERSION__ < 199901L
+/* expected-error@19 {{'long long' is an extension when C99 mode is not enabled}} */
+# endif
+#else
+# if __cplusplus < 201103L
+/* expected-error@19 {{'long long' is a C++11 extension}} */
+# else
+/* expected-warning@19 {{'long long' is incompatible with C++98}} */
+# endif
+#endif
+
+#if 1 > 2LL
+# error should not happen
+#endif
+
diff --git a/test/Sema/c89-2.c b/test/Sema/c89-2.c
deleted file mode 100644
index 14b955a6a4..0000000000
--- a/test/Sema/c89-2.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* RUN: %clang_cc1 %s -std=c89 -pedantic-errors -Wno-empty-translation-unit -verify
- */
-
-#if 1LL /* expected-error {{long long}} */
-#endif
diff --git a/test/Sema/c89.c b/test/Sema/c89.c
index 110d7e1376..a410a626ed 100644
--- a/test/Sema/c89.c
+++ b/test/Sema/c89.c
@@ -110,3 +110,9 @@ typedef CI *array_of_pointer_to_CI[5];
const array_of_pointer_to_CI mine3;
void main() {} /* expected-error {{'main' must return 'int'}} */
+
+long long ll1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
+ -42LL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
+unsigned long long ull1 = /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
+ 42ULL; /* expected-warning {{'long long' is an extension when C99 mode is not enabled}} */
+
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index ec50cb7d92..942bf41474 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -115,7 +115,7 @@ int array2[recurse2]; // expected-warning {{variable length array}} expected-war
namespace FloatConvert {
typedef int a[(int)42.3];
typedef int a[(int)42.997];
- typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is an extension}}
+ typedef int b[(long long)4e20]; // expected-warning {{variable length}} expected-error {{variable length}} expected-warning {{'long long' is a C++11 extension}}
}
// PR12626
diff --git a/test/SemaCXX/cxx98-compat-pedantic.cpp b/test/SemaCXX/cxx98-compat-pedantic.cpp
index c07f64e614..18fd1520ec 100644
--- a/test/SemaCXX/cxx98-compat-pedantic.cpp
+++ b/test/SemaCXX/cxx98-compat-pedantic.cpp
@@ -32,3 +32,9 @@ int *ArraySizeConversion = new int[ConvertToInt()]; // expected-warning {{implic
template<typename T> class ExternTemplate {};
extern template class ExternTemplate<int>; // expected-warning {{extern templates are incompatible with C++98}}
+
+long long ll1 = // expected-warning {{'long long' is incompatible with C++98}}
+ -42LL; // expected-warning {{'long long' is incompatible with C++98}}
+unsigned long long ull1 = // expected-warning {{'long long' is incompatible with C++98}}
+ 42ULL; // expected-warning {{'long long' is incompatible with C++98}}
+