| // PR c++/66561 - __builtin_LINE at al. should yield constant expressions |
| // { dg-do compile { target c++11 } } |
| #define A(expr) static_assert ((expr), #expr) |
| |
| #define FILE_1 "file_name.suffix" |
| #define FILE_2 "some_other_file_name.suffix" |
| |
| #line 1 FILE_1 |
| constexpr const char* |
| file1 () |
| { |
| #if __cplusplus >= 201402L |
| // Do extra checking in C++ 14 and later. |
| constexpr const char *f1 = __FILE__; |
| constexpr const char *f2 = __builtin_FILE (); |
| A (0 == __builtin_strcmp (f1, f2)); |
| return f1; |
| #else |
| // In C++ 11, a constexpr function body must consist of a single |
| // return statement and no declaratations. |
| return __builtin_FILE (); |
| #endif |
| } |
| |
| #line 1 FILE_2 |
| constexpr const char* |
| file2 () |
| { |
| #if __cplusplus >= 201402L |
| constexpr const char *f1 = __FILE__; |
| constexpr const char *f2 = __builtin_FILE (); |
| A (0 == __builtin_strcmp (f1, f2)); |
| return f1; |
| #else |
| return __builtin_FILE (); |
| #endif |
| } |
| |
| #line 1 "bogus file name" |
| constexpr const char* |
| this_file (const char *fname = __builtin_FILE ()) |
| { |
| return fname; |
| } |
| |
| constexpr const char* |
| function () |
| { |
| #if __cplusplus >= 201402L |
| constexpr const char *f1 = __FUNCTION__; |
| constexpr const char *f2 = __builtin_FUNCTION (); |
| A (0 == __builtin_strcmp (f1, f2)); |
| return f1; |
| #else |
| return __builtin_FUNCTION (); |
| #endif |
| } |
| |
| constexpr const char* |
| this_function (const char *func = __builtin_FUNCTION ()) |
| { |
| return func; |
| } |
| |
| constexpr int |
| line () |
| { |
| #if __cplusplus >= 201402L |
| #line 123 |
| constexpr int n1 = __LINE__; |
| constexpr int n2 = __builtin_LINE (); |
| A (123 == n1); |
| A (n1 + 1 == n2); |
| return n2; |
| #else |
| #line 123 |
| // Newline. |
| return __builtin_LINE (); |
| #endif |
| } |
| |
| constexpr int |
| this_line (int line = __builtin_LINE ()) |
| { |
| return line; |
| } |
| |
| |
| // Exercise __builtin_FILE(). |
| #line 1 "foobar" |
| constexpr const char* f1 = file1 (); |
| A (0 == __builtin_strcmp (f1, FILE_1)); |
| |
| #line 2 "foobar" |
| constexpr const char* f2 = file2 (); |
| A (0 == __builtin_strcmp (f2, FILE_2)); |
| |
| #define FILE_3 "this_file_name_right_here.this_suffix" |
| #line 1 FILE_3 |
| constexpr const char* f3 = this_file (); |
| A (0 == __builtin_strcmp (f3, FILE_3)); |
| |
| #define FILE_4 "next_file_name.another_suffix" |
| #line 1 "foobar" |
| constexpr const char* f4 = this_file |
| #line 1 FILE_4 |
| ( |
| #line 1 "foobar" |
| ) |
| ; |
| A (0 == __builtin_strcmp (f4, FILE_4)); |
| |
| |
| // Exercise __builtin_FUNCTION(). |
| |
| // Verify that __builtin_FUNCTION() returns the name of the function |
| // in which it is called. |
| constexpr const char* fun1 = function (); |
| A (0 == __builtin_strcmp (fun1, "function")); |
| |
| // Verify that __builtin_FUNCTION() returns the empty string when |
| // it's invoked to set the default argument value in a function |
| // called at file scope. |
| constexpr const char* fun2 = this_function (); |
| A (0 == __builtin_strcmp (fun2, "")); |
| |
| constexpr const char* |
| named_function () |
| { |
| return this_function (); |
| } |
| |
| constexpr const char* fun3 = named_function (); |
| A (0 == __builtin_strcmp (fun3, "named_function")); |
| |
| |
| // Exercise __builtin_LINE(). |
| // Verify the line numbe returned by the built-in. |
| #line 4 |
| constexpr int n1 = __builtin_LINE (); |
| A (n1 == 4); |
| |
| // Verify the line number obtained by a constexpr function. |
| #line 5 |
| constexpr int n2 = line (); |
| A (n2 == 124); |
| |
| // Verify the line number determined by the default argument. |
| #line 6 |
| constexpr int n3 = this_line (); |
| A (n3 == 6); |
| |
| // Verify that the line number accounts for each of the calls. |
| #line 7 |
| constexpr int n4 = this_line () + this_line (); |
| A (n4 == 14); |
| |
| // Verify that the line number accounts for each of the calls when |
| // split over multiple lines. |
| #line 1 |
| constexpr int n5 = this_line () |
| #line 8 |
| + this_line (); |
| A (n5 == 9); |
| |
| // Verify that the line number corresponds to the closing parenthesis |
| // of the function call. |
| #line 1 |
| constexpr int n6 = this_line |
| #line 99 |
| ( |
| #line 1 |
| ) |
| ; |
| A (n6 == 99); |