================ @@ -0,0 +1,95 @@ +// RUN: %clang_cc1 -verify=expected,c2y -pedantic -std=c2y %s +// RUN: %clang_cc1 -verify=expected,c2y,compat -Wpre-c2y-compat -std=c2y %s +// RUN: %clang_cc1 -verify=expected,ext -pedantic -std=c23 %s +// RUN: %clang_cc1 -verify=expected,ext -pedantic -x c++ -Wno-c11-extensions %s + + +/* WG14 N3353: Clang 21 + * Obsolete implicitly octal literals and add delimited escape sequences + */ + +constexpr int i = 0234; // c2y-warning {{octal literals without a '0o' prefix are deprecated}} +constexpr int j = 0o234; /* ext-warning {{octal integer literals are a C2y extension}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + */ + +static_assert(i == 156); +static_assert(j == 156); + +// Show that 0O is the same as Oo (tested above) +static_assert(0O1234 == 0o1234); /* ext-warning 2 {{octal integer literals are a C2y extension}} + compat-warning 2 {{octal integer literals are incompatible with standards before C2y}} + */ + +// Demonstrate that it works fine in the preprocessor. +#if 0o123 != 0x53 /* ext-warning {{octal integer literals are a C2y extension}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + */ +#error "oh no, math stopped working!" +#endif + +// 0 by itself is not deprecated, of course. +int k = 0; + +// Make sure there are no surprises with auto and type deduction. Promotion +// turns this into an 'int', and 'constexpr' implies 'const'. +constexpr auto l = 0o1234567; /* ext-warning {{octal integer literals are a C2y extension}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + */ +static_assert(l == 0x53977); +static_assert(__extension__ _Generic(typeof(0o1), typeof(01) : 1, default : 0)); /* c2y-warning {{octal literals without a '0o' prefix are deprecated}} + compat-warning {{passing a type argument as the first operand to '_Generic' is incompatible with C standards before C2y}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + */ +static_assert(__extension__ _Generic(typeof(l), const int : 1, default : 0)); // compat-warning {{passing a type argument as the first operand to '_Generic' is incompatible with C standards before C2y}} + +// Note that 0o by itself is an invalid literal. +int m = 0o; /* expected-error {{invalid suffix 'o' on integer constant}} + c2y-warning {{octal literals without a '0o' prefix are deprecated}} + */ + +// Ensure negation works as expected. +static_assert(-0o1234 == -668); /* ext-warning {{octal integer literals are a C2y extension}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + */ + +// FIXME: it would be better to not diagnose the compat and ext warnings when +// the octal literal is invalid. +// We expect diagnostics for non-octal digits. +int n = 0o18; /* expected-error {{invalid digit '8' in octal constant}} + compat-warning {{octal integer literals are incompatible with standards before C2y}} + ext-warning {{octal integer literals are a C2y extension}} + */ +int o1 = 0o8; /* expected-error {{invalid suffix 'o8' on integer constant}} + c2y-warning {{octal literals without a '0o' prefix are deprecated}} + */ ---------------- AaronBallman wrote:
That's a significantly more invasive change than I think should be handled in this patch (it's the same behavior as with other prefixes like `0xG`, just that we don't have the deprecation warning). I've been trying to figure out how to silence that warning in the presence of errors and it's not been straightforward so far. Still looking to see if it's possible, but as for the error, I think that's follow-up work. https://github.com/llvm/llvm-project/pull/131626 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits