blob: 1f8a7fd7bb6ce7ee8b026403513e6f4e4c42c9db [file] [log] [blame]
// 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);