@@ -351,3 +351,96 @@ namespace EhReturnDataRegno {
351
351
__builtin_eh_return_data_regno (X); // both-error {{argument to '__builtin_eh_return_data_regno' must be a constant integer}}
352
352
}
353
353
}
354
+
355
+ // / From test/SemaCXX/builtins.cpp
356
+ namespace test_launder {
357
+ #define TEST_TYPE (Ptr, Type ) \
358
+ static_assert (__is_same(decltype (__builtin_launder(Ptr)), Type), " expected same type" )
359
+
360
+ struct Dummy {};
361
+
362
+ using FnType = int (char );
363
+ using MemFnType = int (Dummy::*)(char );
364
+ using ConstMemFnType = int (Dummy::*)() const ;
365
+
366
+ void foo () {}
367
+
368
+ void test_builtin_launder_diags (void *vp, const void *cvp, FnType *fnp,
369
+ MemFnType mfp, ConstMemFnType cmfp, int (&Arr)[5]) {
370
+ __builtin_launder (vp); // both-error {{void pointer argument to '__builtin_launder' is not allowed}}
371
+ __builtin_launder (cvp); // both-error {{void pointer argument to '__builtin_launder' is not allowed}}
372
+ __builtin_launder (fnp); // both-error {{function pointer argument to '__builtin_launder' is not allowed}}
373
+ __builtin_launder (mfp); // both-error {{non-pointer argument to '__builtin_launder' is not allowed}}
374
+ __builtin_launder (cmfp); // both-error {{non-pointer argument to '__builtin_launder' is not allowed}}
375
+ (void )__builtin_launder (&fnp);
376
+ __builtin_launder (42 ); // both-error {{non-pointer argument to '__builtin_launder' is not allowed}}
377
+ __builtin_launder (nullptr ); // both-error {{non-pointer argument to '__builtin_launder' is not allowed}}
378
+ __builtin_launder (foo); // both-error {{function pointer argument to '__builtin_launder' is not allowed}}
379
+ (void )__builtin_launder (Arr);
380
+ }
381
+
382
+ void test_builtin_launder (char *p, const volatile int *ip, const float *&fp,
383
+ double *__restrict dp) {
384
+ int x;
385
+ __builtin_launder (x); // both-error {{non-pointer argument to '__builtin_launder' is not allowed}}
386
+
387
+ TEST_TYPE (p, char *);
388
+ TEST_TYPE (ip, const volatile int *);
389
+ TEST_TYPE (fp, const float *);
390
+ TEST_TYPE (dp, double *__restrict);
391
+
392
+ char *d = __builtin_launder (p);
393
+ const volatile int *id = __builtin_launder (ip);
394
+ int *id2 = __builtin_launder (ip); // both-error {{cannot initialize a variable of type 'int *' with an rvalue of type 'const volatile int *'}}
395
+ const float * fd = __builtin_launder (fp);
396
+ }
397
+
398
+ void test_launder_return_type (const int (&ArrayRef)[101], int (&MArrRef)[42][13],
399
+ void (**&FuncPtrRef)()) {
400
+ TEST_TYPE (ArrayRef, const int *);
401
+ TEST_TYPE (MArrRef, int (*)[13 ]);
402
+ TEST_TYPE (FuncPtrRef, void (**)());
403
+ }
404
+
405
+ template <class Tp >
406
+ constexpr Tp *test_constexpr_launder (Tp *tp) {
407
+ return __builtin_launder (tp);
408
+ }
409
+ constexpr int const_int = 42 ;
410
+ constexpr int const_int2 = 101 ;
411
+ constexpr const int *const_ptr = test_constexpr_launder(&const_int);
412
+ static_assert (&const_int == const_ptr, " " );
413
+ static_assert (const_ptr != test_constexpr_launder(&const_int2), " " );
414
+
415
+ void test_non_constexpr () {
416
+ constexpr int i = 42 ; // both-note {{address of non-static constexpr variable 'i' may differ on each invocation}}
417
+ constexpr const int *ip = __builtin_launder (&i); // both-error {{constexpr variable 'ip' must be initialized by a constant expression}}
418
+ // both-note@-1 {{pointer to 'i' is not a constant expression}}
419
+ }
420
+
421
+ constexpr bool test_in_constexpr (const int &i) {
422
+ return (__builtin_launder (&i) == &i);
423
+ }
424
+
425
+ static_assert (test_in_constexpr(const_int), " " );
426
+ void f () {
427
+ constexpr int i = 42 ;
428
+ static_assert (test_in_constexpr (i), " " );
429
+ }
430
+
431
+ struct Incomplete ; // both-note {{forward declaration}}
432
+ struct IncompleteMember {
433
+ Incomplete &i;
434
+ };
435
+ void test_incomplete (Incomplete *i, IncompleteMember *im) {
436
+ // both-error@+1 {{incomplete type 'Incomplete' where a complete type is required}}
437
+ __builtin_launder (i);
438
+ __builtin_launder (&i); // OK
439
+ __builtin_launder (im); // OK
440
+ }
441
+
442
+ void test_noexcept (int *i) {
443
+ static_assert (noexcept (__builtin_launder (i)), " " );
444
+ }
445
+ #undef TEST_TYPE
446
+ } // end namespace test_launder
0 commit comments