brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · 5620841 Raw
189 lines · c
1// RUN: %clang_cc1 -verify -ffreestanding -Wno-unused -std=c2x %s2 3/* WG14 N3042: full4 * Introduce the nullptr constant5 */6 7#include <stddef.h>8 9// FIXME: The paper calls for a feature testing macro to be added to stddef.h10// which we do not implement. This should be addressed after WG14 has processed11// national body comments for C2x as we've asked for the feature test macros to12// be removed.13#ifndef __STDC_VERSION_STDDEF_H__14#error "no version macro for stddef.h"15#endif16// expected-error@-2 {{"no version macro for stddef.h"}}17 18void questionable_behaviors() {19  nullptr_t val;20 21  // This code is intended to be rejected by C and is accepted by C++. We filed22  // an NB comment asking for this to be changed, but WG14 declined.23  (void)(1 ? val : 0);     // expected-error {{non-pointer operand type 'int' incompatible with nullptr}}24  (void)(1 ? nullptr : 0); // expected-error {{non-pointer operand type 'int' incompatible with nullptr}}25 26  // This code is intended to be accepted by C and is rejected by C++. We filed27  // an NB comment asking for this to be changed, but WG14 declined.28  _Bool another = val;    // expected-warning {{implicit conversion of nullptr constant to 'bool'}}29  another = val;          // expected-warning {{implicit conversion of nullptr constant to 'bool'}}30  _Bool again = nullptr;  // expected-warning {{implicit conversion of nullptr constant to 'bool'}}31  again = nullptr;        // expected-warning {{implicit conversion of nullptr constant to 'bool'}}32}33 34void test() {35  // Can we declare the type?36  nullptr_t null_val;37 38  // Can we use the keyword?39  int *typed_ptr = nullptr;40  typed_ptr = nullptr;41 42  // Can we use the keyword with the type?43  null_val = nullptr;44  // Even initialize with it?45  nullptr_t ignore = nullptr;46 47  // Can we assign an object of the type to another object of the same type?48  null_val = null_val;49 50  // Can we assign nullptr_t objects to pointer objects?51  typed_ptr = null_val;52 53  // Can we take the address of an object of type nullptr_t?54  &null_val;55 56  // How about the null pointer named constant?57  &nullptr; // expected-error {{cannot take the address of an rvalue of type 'nullptr_t'}}58 59  // Assignment from a null pointer constant to a nullptr_t is valid.60  null_val = 0;61  null_val = (void *)0;62 63  // Assignment from a nullptr_t to a pointer is also valid.64  typed_ptr = null_val;65  void *other_ptr = null_val;66 67  // Can it be used in all the places a scalar can be used?68  if (null_val) {}     // expected-warning {{implicit conversion of nullptr constant to 'bool'}}69  if (!null_val) {}    // expected-warning {{implicit conversion of nullptr constant to 'bool'}}70  for (;null_val;) {}  // expected-warning {{implicit conversion of nullptr constant to 'bool'}}71  while (nullptr) {}   // expected-warning {{implicit conversion of nullptr constant to 'bool'}}72  null_val && nullptr; // expected-warning {{implicit conversion of nullptr constant to 'bool'}} \73                          expected-warning {{implicit conversion of nullptr constant to 'bool'}}74  nullptr || null_val; // expected-warning {{implicit conversion of nullptr constant to 'bool'}} \75                          expected-warning {{implicit conversion of nullptr constant to 'bool'}}76  null_val ? 0 : 1;    // expected-warning {{implicit conversion of nullptr constant to 'bool'}}77  sizeof(null_val);78  alignas(nullptr_t) int aligned;79 80  // Cast expressions have special handling for nullptr_t despite allowing81  // casts of scalar types.82  (nullptr_t)12;        // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}83  (float)null_val;      // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}84  (float)nullptr;       // expected-error {{cannot cast an object of type 'nullptr_t' to 'float'}}85  (nullptr_t)(int *)12; // expected-error {{cannot cast an object of type 'int *' to 'nullptr_t'}}86  (nullptr_t)"testing"; // expected-error {{cannot cast an object of type 'char *' to 'nullptr_t'}}87  (nullptr_t)1.0f;      // expected-error {{cannot cast an object of type 'float' to 'nullptr_t'}}88  (nullptr_t)'a';       // expected-error {{cannot cast an object of type 'int' to 'nullptr_t'}}89 90  (void)null_val;     // ok91  (void)nullptr;      // ok92  (bool)null_val;     // ok93  (bool)nullptr;      // ok94  (int *)null_val;    // ok95  (int *)nullptr;     // ok96  (nullptr_t)nullptr; // ok97  (nullptr_t)0;       // ok98  (nullptr_t)(void *)0; // ok99  (nullptr_t)null_val;  // ok100 101  // Can it be converted to bool with the result false (this relies on Clang102  // accepting additional kinds of constant expressions where an ICE is103  // required)?104  static_assert(!nullptr);  // expected-warning {{implicit conversion of nullptr constant to 'bool'}}105  static_assert(!null_val); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}106  static_assert(nullptr);   // expected-error {{static assertion failed due to requirement 'nullptr'}} \107                               expected-warning {{implicit conversion of nullptr constant to 'bool'}}108  static_assert(null_val);  // expected-error {{static assertion failed due to requirement 'null_val'}} \109                               expected-warning {{implicit conversion of nullptr constant to 'bool'}}110 111  // Do equality operators work as expected with it?112  static_assert(nullptr == nullptr);113  static_assert(null_val == null_val);114  static_assert(nullptr != (int*)1);115  static_assert(null_val != (int*)1);116  static_assert(nullptr == null_val);117  static_assert(nullptr == 0);118  static_assert(null_val == (void *)0);119 120  // None of the relational operators should succeed.121  (void)(null_val <= 0);            // expected-error {{invalid operands to binary expression ('nullptr_t' and 'int')}}122  (void)(null_val >= (void *)0);    // expected-error {{invalid operands to binary expression ('nullptr_t' and 'void *')}}123  (void)(!(null_val < (void *)0));  // expected-error {{invalid operands to binary expression ('nullptr_t' and 'void *')}}124  (void)(!(null_val > 0));          // expected-error {{invalid operands to binary expression ('nullptr_t' and 'int')}}125  (void)(nullptr <= 0);             // expected-error {{invalid operands to binary expression ('nullptr_t' and 'int')}}126  (void)(nullptr >= (void *)0);     // expected-error {{invalid operands to binary expression ('nullptr_t' and 'void *')}}127  (void)(!(nullptr < (void *)0));   // expected-error {{invalid operands to binary expression ('nullptr_t' and 'void *')}}128  (void)(!(nullptr > 0));           // expected-error {{invalid operands to binary expression ('nullptr_t' and 'int')}}129  (void)(null_val <= null_val);     // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}130  (void)(null_val >= null_val);     // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}131  (void)(!(null_val < null_val));   // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}132  (void)(!(null_val > null_val));   // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}133  (void)(null_val <= nullptr);      // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}134  (void)(null_val >= nullptr);      // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}135  (void)(!(null_val < nullptr));    // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}136  (void)(!(null_val > nullptr));    // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}137  (void)(nullptr <= nullptr);       // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}138  (void)(nullptr >= nullptr);       // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}139  (void)(!(nullptr < nullptr));     // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}140  (void)(!(nullptr > nullptr));     // expected-error {{invalid operands to binary expression ('nullptr_t' and 'nullptr_t')}}141 142  // Do we pick the correct common type for conditional operators?143  _Generic(1 ? nullptr : nullptr, nullptr_t : 0);144  _Generic(1 ? null_val : null_val, nullptr_t : 0);145  _Generic(1 ? typed_ptr : null_val, typeof(typed_ptr) : 0);146  _Generic(1 ? null_val : typed_ptr, typeof(typed_ptr) : 0);147  _Generic(1 ? nullptr : typed_ptr, typeof(typed_ptr) : 0);148  _Generic(1 ? typed_ptr : nullptr, typeof(typed_ptr) : 0);149 150  // Same for GNU conditional operators?151  _Generic(nullptr ?: nullptr, nullptr_t : 0);            // expected-warning {{implicit conversion of nullptr constant to 'bool'}}152  _Generic(null_val ?: null_val, nullptr_t : 0);          // expected-warning {{implicit conversion of nullptr constant to 'bool'}}153  _Generic(typed_ptr ?: null_val, typeof(typed_ptr) : 0);154  _Generic(null_val ?: typed_ptr, typeof(typed_ptr) : 0); // expected-warning {{implicit conversion of nullptr constant to 'bool'}}155  _Generic(nullptr ?: typed_ptr, typeof(typed_ptr) : 0);  // expected-warning {{implicit conversion of nullptr constant to 'bool'}}156  _Generic(typed_ptr ?: nullptr, typeof(typed_ptr) : 0);157 158  // Do we correctly issue type incompatibility diagnostics?159  int i = nullptr;   // expected-error {{initializing 'int' with an expression of incompatible type 'nullptr_t'}}160  float f = nullptr; // expected-error {{initializing 'float' with an expression of incompatible type 'nullptr_t'}}161  i = null_val;      // expected-error {{assigning to 'int' from incompatible type 'nullptr_t'}}162  f = null_val;      // expected-error {{assigning to 'float' from incompatible type 'nullptr_t'}}163  null_val = i;      // expected-error {{assigning to 'nullptr_t' from incompatible type 'int'}}164  null_val = f;      // expected-error {{assigning to 'nullptr_t' from incompatible type 'float'}}165}166 167// Can we use it as a function parameter?168void null_param(nullptr_t);169 170void other_test() {171  // Can we call the function properly?172  null_param(nullptr);173 174  // We can pass any kind of null pointer constant.175  null_param((void *)0);176  null_param(0);177}178 179 180void printf(const char*, ...) __attribute__((format(printf, 1, 2)));181void format_specifiers() {182  // Don't warn when using nullptr with %p.183  printf("%p", nullptr);184}185 186// Ensure that conversion from a null pointer constant to nullptr_t is187// valid in a constant expression.188static_assert((nullptr_t){} == 0);189