View | Details | Return to bug 101539 | Differences between
and this patch

Collapse All | Expand All

(-)gcc/c-family/c-common.h.jj (+1 lines)
Lines 174-179 enum rid Link Here
174
  RID_IS_BASE_OF,              RID_IS_CLASS,
174
  RID_IS_BASE_OF,              RID_IS_CLASS,
175
  RID_IS_EMPTY,                RID_IS_ENUM,
175
  RID_IS_EMPTY,                RID_IS_ENUM,
176
  RID_IS_FINAL,                RID_IS_LITERAL_TYPE,
176
  RID_IS_FINAL,                RID_IS_LITERAL_TYPE,
177
  RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF,
177
  RID_IS_POD,                  RID_IS_POLYMORPHIC,
178
  RID_IS_POD,                  RID_IS_POLYMORPHIC,
178
  RID_IS_SAME_AS,
179
  RID_IS_SAME_AS,
179
  RID_IS_STD_LAYOUT,           RID_IS_TRIVIAL,
180
  RID_IS_STD_LAYOUT,           RID_IS_TRIVIAL,
(-)gcc/c-family/c-common.c.jj (+2 lines)
Lines 421-426 const struct c_common_resword c_common_r Link Here
421
  { "__is_enum",	RID_IS_ENUM,	D_CXXONLY },
421
  { "__is_enum",	RID_IS_ENUM,	D_CXXONLY },
422
  { "__is_final",	RID_IS_FINAL,	D_CXXONLY },
422
  { "__is_final",	RID_IS_FINAL,	D_CXXONLY },
423
  { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY },
423
  { "__is_literal_type", RID_IS_LITERAL_TYPE, D_CXXONLY },
424
  { "__is_pointer_interconvertible_base_of",
425
			RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF, D_CXXONLY },
424
  { "__is_pod",		RID_IS_POD,	D_CXXONLY },
426
  { "__is_pod",		RID_IS_POD,	D_CXXONLY },
425
  { "__is_polymorphic",	RID_IS_POLYMORPHIC, D_CXXONLY },
427
  { "__is_polymorphic",	RID_IS_POLYMORPHIC, D_CXXONLY },
426
  { "__is_same",     RID_IS_SAME_AS, D_CXXONLY },
428
  { "__is_same",     RID_IS_SAME_AS, D_CXXONLY },
(-)gcc/cp/cp-tree.h.jj (+3 lines)
Lines 1366-1371 enum cp_trait_kind Link Here
1366
  CPTK_IS_ENUM,
1366
  CPTK_IS_ENUM,
1367
  CPTK_IS_FINAL,
1367
  CPTK_IS_FINAL,
1368
  CPTK_IS_LITERAL_TYPE,
1368
  CPTK_IS_LITERAL_TYPE,
1369
  CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF,
1369
  CPTK_IS_POD,
1370
  CPTK_IS_POD,
1370
  CPTK_IS_POLYMORPHIC,
1371
  CPTK_IS_POLYMORPHIC,
1371
  CPTK_IS_SAME_AS,
1372
  CPTK_IS_SAME_AS,
Lines 6355-6360 struct GTY((chain_next ("%h.next"))) tin Link Here
6355
enum cp_built_in_function {
6356
enum cp_built_in_function {
6356
  CP_BUILT_IN_IS_CONSTANT_EVALUATED,
6357
  CP_BUILT_IN_IS_CONSTANT_EVALUATED,
6357
  CP_BUILT_IN_INTEGER_PACK,
6358
  CP_BUILT_IN_INTEGER_PACK,
6359
  CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
6358
  CP_BUILT_IN_SOURCE_LOCATION,
6360
  CP_BUILT_IN_SOURCE_LOCATION,
6359
  CP_BUILT_IN_LAST
6361
  CP_BUILT_IN_LAST
6360
};
6362
};
Lines 7570-7575 extern tree baselink_for_fns Link Here
7570
extern void finish_static_assert                (tree, tree, location_t,
7572
extern void finish_static_assert                (tree, tree, location_t,
7571
						 bool, bool);
7573
						 bool, bool);
7572
extern tree finish_decltype_type                (tree, bool, tsubst_flags_t);
7574
extern tree finish_decltype_type                (tree, bool, tsubst_flags_t);
7575
extern tree fold_builtin_is_pointer_inverconvertible_with_class (location_t, int, tree *);
7573
extern tree finish_trait_expr			(location_t, enum cp_trait_kind, tree, tree);
7576
extern tree finish_trait_expr			(location_t, enum cp_trait_kind, tree, tree);
7574
extern tree build_lambda_expr                   (void);
7577
extern tree build_lambda_expr                   (void);
7575
extern tree build_lambda_object			(tree);
7578
extern tree build_lambda_object			(tree);
(-)gcc/cp/parser.c.jj (+5 lines)
Lines 5797-5802 cp_parser_primary_expression (cp_parser Link Here
5797
	case RID_IS_ENUM:
5797
	case RID_IS_ENUM:
5798
	case RID_IS_FINAL:
5798
	case RID_IS_FINAL:
5799
	case RID_IS_LITERAL_TYPE:
5799
	case RID_IS_LITERAL_TYPE:
5800
	case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
5800
	case RID_IS_POD:
5801
	case RID_IS_POD:
5801
	case RID_IS_POLYMORPHIC:
5802
	case RID_IS_POLYMORPHIC:
5802
	case RID_IS_SAME_AS:
5803
	case RID_IS_SAME_AS:
Lines 10686-10691 cp_parser_trait_expr (cp_parser* parser, Link Here
10686
    case RID_IS_LITERAL_TYPE:
10687
    case RID_IS_LITERAL_TYPE:
10687
      kind = CPTK_IS_LITERAL_TYPE;
10688
      kind = CPTK_IS_LITERAL_TYPE;
10688
      break;
10689
      break;
10690
    case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
10691
      kind = CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF;
10692
      binary = true;
10693
      break;
10689
    case RID_IS_POD:
10694
    case RID_IS_POD:
10690
      kind = CPTK_IS_POD;
10695
      kind = CPTK_IS_POD;
10691
      break;
10696
      break;
(-)gcc/cp/cp-objcp-common.c.jj (+1 lines)
Lines 414-419 names_builtin_p (const char *name) Link Here
414
    case RID_IS_ENUM:
414
    case RID_IS_ENUM:
415
    case RID_IS_FINAL:
415
    case RID_IS_FINAL:
416
    case RID_IS_LITERAL_TYPE:
416
    case RID_IS_LITERAL_TYPE:
417
    case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
417
    case RID_IS_POD:
418
    case RID_IS_POD:
418
    case RID_IS_POLYMORPHIC:
419
    case RID_IS_POLYMORPHIC:
419
    case RID_IS_SAME_AS:
420
    case RID_IS_SAME_AS:
(-)gcc/cp/constraint.cc.jj (+4 lines)
Lines 3631-3636 diagnose_trait_expr (tree expr, tree arg Link Here
3631
    case CPTK_IS_LITERAL_TYPE:
3631
    case CPTK_IS_LITERAL_TYPE:
3632
      inform (loc, "  %qT is not a literal type", t1);
3632
      inform (loc, "  %qT is not a literal type", t1);
3633
      break;
3633
      break;
3634
    case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
3635
      inform (loc, "  %qT is not pointer-interconvertible base of %qT",
3636
	      t1, t2);
3637
      break;
3634
    case CPTK_IS_POD:
3638
    case CPTK_IS_POD:
3635
      inform (loc, "  %qT is not a POD type", t1);
3639
      inform (loc, "  %qT is not a POD type", t1);
3636
      break;
3640
      break;
(-)gcc/cp/decl.c.jj (+9 lines)
Lines 4467-4472 cxx_init_decl_processing (void) Link Here
4467
			       BUILT_IN_FRONTEND, NULL, NULL_TREE);
4467
			       BUILT_IN_FRONTEND, NULL, NULL_TREE);
4468
  set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
4468
  set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
4469
4469
4470
  tree bool_vaftype = build_varargs_function_type_list (boolean_type_node,
4471
							NULL_TREE);
4472
  decl
4473
    = add_builtin_function ("__builtin_is_pointer_interconvertible_with_class",
4474
			    bool_vaftype,
4475
			    CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
4476
			    BUILT_IN_FRONTEND, NULL, NULL_TREE);
4477
  set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);
4478
4470
  integer_two_node = build_int_cst (NULL_TREE, 2);
4479
  integer_two_node = build_int_cst (NULL_TREE, 2);
4471
4480
4472
  /* Guess at the initial static decls size.  */
4481
  /* Guess at the initial static decls size.  */
(-)gcc/cp/constexpr.c.jj (-2 / +14 lines)
Lines 1427-1434 cxx_eval_builtin_function_call (const co Link Here
1427
      && ctx->call
1427
      && ctx->call
1428
      && ctx->call->fundef)
1428
      && ctx->call->fundef)
1429
    current_function_decl = ctx->call->fundef->decl;
1429
    current_function_decl = ctx->call->fundef->decl;
1430
  new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
1430
  if (fndecl_built_in_p (fun,
1431
				      CALL_EXPR_FN (t), nargs, args);
1431
			 CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
1432
			 BUILT_IN_FRONTEND))
1433
    {
1434
      location_t loc = EXPR_LOCATION (t);
1435
      if (nargs >= 1)
1436
	VERIFY_CONSTANT (args[0]);
1437
      new_call
1438
	= fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
1439
							       args);
1440
    }
1441
  else
1442
    new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
1443
					CALL_EXPR_FN (t), nargs, args);
1432
  current_function_decl = save_cur_fn;
1444
  current_function_decl = save_cur_fn;
1433
  force_folding_builtin_constant_p = save_ffbcp;
1445
  force_folding_builtin_constant_p = save_ffbcp;
1434
  if (new_call == NULL)
1446
  if (new_call == NULL)
(-)gcc/cp/semantics.c.jj (-3 / +136 lines)
Lines 10566-10571 classtype_has_nothrow_assign_or_copy_p ( Link Here
10566
  return saw_copy;
10566
  return saw_copy;
10567
}
10567
}
10568
10568
10569
/* Helper function for pointer_interconvertible_base_of_p.  Verify
10570
   that BINFO_TYPE (BINFO) is pointer interconvertible with BASE.  */
10571
10572
static bool
10573
pointer_interconvertible_base_of_p_1 (tree binfo, tree base)
10574
{
10575
  for (tree field = TYPE_FIELDS (BINFO_TYPE (binfo));
10576
       field; field = DECL_CHAIN (field))
10577
    if (TREE_CODE (field) == FIELD_DECL && !DECL_FIELD_IS_BASE (field))
10578
      return false;
10579
10580
  unsigned ix;
10581
  tree base_binfo;
10582
  for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
10583
    if (SAME_BINFO_TYPE_P (BINFO_TYPE (base_binfo), base)
10584
	|| pointer_interconvertible_base_of_p_1 (base_binfo, base))
10585
      return true;
10586
  return false;
10587
}
10588
10589
/* Return true if DERIVED is pointer interconvertible base of BASE.  */
10590
10591
static bool
10592
pointer_interconvertible_base_of_p (tree base, tree derived)
10593
{
10594
  if (base == error_mark_node || derived == error_mark_node)
10595
    return false;
10596
  base = cp_build_qualified_type (base, TYPE_UNQUALIFIED);
10597
  derived = cp_build_qualified_type (derived, TYPE_UNQUALIFIED);
10598
  if (NON_UNION_CLASS_TYPE_P (base)
10599
      && NON_UNION_CLASS_TYPE_P (derived)
10600
      && same_type_p (base, derived))
10601
    return true;
10602
10603
  if (!complete_type_or_else (derived, NULL_TREE))
10604
    return false;
10605
10606
  if (!uniquely_derived_from_p (base, derived))
10607
    return false;
10608
10609
  if (!std_layout_type_p (derived))
10610
    return false;
10611
10612
  return pointer_interconvertible_base_of_p_1 (TYPE_BINFO (derived), base);
10613
}
10614
10615
/* Helper function for fold_builtin_is_pointer_inverconvertible_with_class,
10616
   return true if MEMBERTYPE is the type of the first non-static data member
10617
   of TYPE or for unions of any members.  */
10618
static bool
10619
first_nonstatic_data_member_p (tree type, tree membertype)
10620
{
10621
  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
10622
    {
10623
      if (TREE_CODE (field) != FIELD_DECL)
10624
	continue;
10625
      if (DECL_FIELD_IS_BASE (field) && is_empty_field (field))
10626
	continue;
10627
      if (DECL_FIELD_IS_BASE (field))
10628
	return first_nonstatic_data_member_p (TREE_TYPE (field), membertype);
10629
      if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
10630
	{
10631
	  if (TREE_CODE (type) != UNION_TYPE)
10632
	    return first_nonstatic_data_member_p (TREE_TYPE (field),
10633
						  membertype);
10634
	  if (first_nonstatic_data_member_p (TREE_TYPE (field), membertype))
10635
	    return true;
10636
	}
10637
      else if (TREE_CODE (type) != UNION_TYPE)
10638
	return same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
10639
							  membertype);
10640
      else if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (field),
10641
							  membertype))
10642
	return true;
10643
    }
10644
  return false;
10645
}
10646
10647
/* Fold __builtin_is_pointer_interconvertible_with_class call.  */
10648
10649
tree
10650
fold_builtin_is_pointer_inverconvertible_with_class (location_t loc, int nargs,
10651
						     tree *args)
10652
{
10653
  /* Unless users call the builtin directly, the following 3 checks should be
10654
     ensured from std::is_pointer_interconvertible_with_class function
10655
     template.  */
10656
  if (nargs != 1)
10657
    {
10658
      error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
10659
		     "needs a single argument");
10660
      return boolean_false_node;
10661
    }
10662
  tree arg = args[0];
10663
  if (error_operand_p (arg))
10664
    return boolean_false_node;
10665
  if (!TYPE_PTRMEM_P (TREE_TYPE (arg)))
10666
    {
10667
      error_at (loc, "%<__builtin_is_pointer_interconvertible_with_class%> "
10668
		     "argument is not pointer to member");
10669
      return boolean_false_node;
10670
    }
10671
10672
  if (!TYPE_PTRDATAMEM_P (TREE_TYPE (arg)))
10673
    return boolean_false_node;
10674
10675
  tree membertype = TREE_TYPE (TREE_TYPE (arg));
10676
  tree basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (arg));
10677
  if (!complete_type_or_else (basetype, NULL_TREE))
10678
    return boolean_false_node;
10679
10680
  if (!std_layout_type_p (basetype))
10681
    return boolean_false_node;
10682
10683
  if (!first_nonstatic_data_member_p (basetype, membertype))
10684
    return boolean_false_node;
10685
10686
  if (TREE_CODE (arg) == PTRMEM_CST)
10687
    arg = cplus_expand_constant (arg);
10688
10689
  if (integer_nonzerop (arg))
10690
    return boolean_false_node;
10691
  if (integer_zerop (arg))
10692
    return boolean_true_node;
10693
10694
  return fold_build2 (EQ_EXPR, boolean_type_node, arg,
10695
		      build_zero_cst (TREE_TYPE (arg)));
10696
}
10697
10569
/* Actually evaluates the trait.  */
10698
/* Actually evaluates the trait.  */
10570
10699
10571
static bool
10700
static bool
Lines 10659-10664 trait_expr_value (cp_trait_kind kind, tr Link Here
10659
    case CPTK_IS_LITERAL_TYPE:
10788
    case CPTK_IS_LITERAL_TYPE:
10660
      return literal_type_p (type1);
10789
      return literal_type_p (type1);
10661
10790
10791
    case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
10792
      return pointer_interconvertible_base_of_p (type1, type2);
10793
10662
    case CPTK_IS_POD:
10794
    case CPTK_IS_POD:
10663
      return pod_type_p (type1);
10795
      return pod_type_p (type1);
10664
10796
Lines 10786-10791 finish_trait_expr (location_t loc, cp_tr Link Here
10786
      break;
10918
      break;
10787
10919
10788
    case CPTK_IS_BASE_OF:
10920
    case CPTK_IS_BASE_OF:
10921
    case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
10789
      if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
10922
      if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2)
10790
	  && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
10923
	  && !same_type_ignoring_top_level_qualifiers_p (type1, type2)
10791
	  && !complete_type_or_else (type2, NULL_TREE))
10924
	  && !complete_type_or_else (type2, NULL_TREE))
Lines 10803-10811 finish_trait_expr (location_t loc, cp_tr Link Here
10803
      gcc_unreachable ();
10936
      gcc_unreachable ();
10804
    }
10937
    }
10805
10938
10806
tree val = (trait_expr_value (kind, type1, type2)
10939
  tree val = (trait_expr_value (kind, type1, type2)
10807
	    ? boolean_true_node : boolean_false_node);
10940
	      ? boolean_true_node : boolean_false_node);
10808
 return maybe_wrap_with_location (val, loc);
10941
  return maybe_wrap_with_location (val, loc);
10809
}
10942
}
10810
10943
10811
/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
10944
/* Do-nothing variants of functions to handle pragma FLOAT_CONST_DECIMAL64,
(-)gcc/cp/cp-gimplify.c.jj (-13 / +37 lines)
Lines 648-661 cp_gimplify_expr (tree *expr_p, gimple_s Link Here
648
      if (ret != GS_ERROR)
648
      if (ret != GS_ERROR)
649
	{
649
	{
650
	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
650
	  tree decl = cp_get_callee_fndecl_nofold (*expr_p);
651
	  if (decl
651
	  if (decl && fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
652
	      && fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
652
	    switch (DECL_FE_FUNCTION_CODE (decl))
653
				    BUILT_IN_FRONTEND))
653
	      {
654
	    *expr_p = boolean_false_node;
654
	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
655
	  else if (decl
655
		*expr_p = boolean_false_node;
656
		   && fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION,
656
		break;
657
					 BUILT_IN_FRONTEND))
657
	      case CP_BUILT_IN_SOURCE_LOCATION:
658
	    *expr_p = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
658
		*expr_p
659
		  = fold_builtin_source_location (EXPR_LOCATION (*expr_p));
660
		break;
661
	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
662
		*expr_p
663
		  = fold_builtin_is_pointer_inverconvertible_with_class
664
			(EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
665
			 &CALL_EXPR_ARG (*expr_p, 0));
666
		break;
667
	      }
659
	}
668
	}
660
      break;
669
      break;
661
670
Lines 2560-2570 cp_fold (tree x) Link Here
2560
	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2569
	    && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
2561
	  nw = 1;
2570
	  nw = 1;
2562
2571
2563
	/* Defer folding __builtin_is_constant_evaluated.  */
2572
	if (callee && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
2564
	if (callee
2573
	  {
2565
	    && fndecl_built_in_p (callee, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
2574
	    switch (DECL_FE_FUNCTION_CODE (callee))
2566
				  BUILT_IN_FRONTEND))
2575
	      {
2567
	  break;
2576
		/* Defer folding __builtin_is_constant_evaluated.  */
2577
	      case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
2578
		break;
2579
	      case CP_BUILT_IN_SOURCE_LOCATION:
2580
		x = fold_builtin_source_location (EXPR_LOCATION (x));
2581
		break;
2582
	      case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
2583
                x = fold_builtin_is_pointer_inverconvertible_with_class
2584
			(EXPR_LOCATION (x), call_expr_nargs (x),
2585
			 &CALL_EXPR_ARG (x, 0));
2586
		break;
2587
	      default:
2588
		break;
2589
	      }
2590
	    break;
2591
	  }
2568
2592
2569
	if (callee
2593
	if (callee
2570
	    && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
2594
	    && fndecl_built_in_p (callee, CP_BUILT_IN_SOURCE_LOCATION,
(-)gcc/cp/tree.c.jj (-5 / +10 lines)
Lines 450-460 builtin_valid_in_constant_expr_p (const_ Link Here
450
    return false;
450
    return false;
451
  if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
451
  if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
452
    {
452
    {
453
      if (fndecl_built_in_p (decl, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
453
      if (fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
454
			     BUILT_IN_FRONTEND)
454
	switch (DECL_FE_FUNCTION_CODE (decl))
455
	  || fndecl_built_in_p (decl, CP_BUILT_IN_SOURCE_LOCATION,
455
	  {
456
				BUILT_IN_FRONTEND))
456
	  case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
457
	return true;
457
	  case CP_BUILT_IN_SOURCE_LOCATION:
458
	  case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
459
	    return true;
460
	  default:
461
	    break;
462
	  }
458
      /* Not a built-in.  */
463
      /* Not a built-in.  */
459
      return false;
464
      return false;
460
    }
465
    }
(-)gcc/cp/cxx-pretty-print.c.jj (-1 / +6 lines)
Lines 2645-2650 pp_cxx_trait_expression (cxx_pretty_prin Link Here
2645
    case CPTK_IS_FINAL:
2645
    case CPTK_IS_FINAL:
2646
      pp_cxx_ws_string (pp, "__is_final");
2646
      pp_cxx_ws_string (pp, "__is_final");
2647
      break;
2647
      break;
2648
    case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
2649
      pp_cxx_ws_string (pp, "__is_pointer_interconvertible_base_of");
2650
      break;
2648
    case CPTK_IS_POD:
2651
    case CPTK_IS_POD:
2649
      pp_cxx_ws_string (pp, "__is_pod");
2652
      pp_cxx_ws_string (pp, "__is_pod");
2650
      break;
2653
      break;
Lines 2695-2701 pp_cxx_trait_expression (cxx_pretty_prin Link Here
2695
  pp_cxx_left_paren (pp);
2698
  pp_cxx_left_paren (pp);
2696
  pp->type_id (TRAIT_EXPR_TYPE1 (t));
2699
  pp->type_id (TRAIT_EXPR_TYPE1 (t));
2697
2700
2698
  if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_SAME_AS)
2701
  if (kind == CPTK_IS_BASE_OF
2702
      || kind == CPTK_IS_SAME_AS
2703
      || kind == CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF)
2699
    {
2704
    {
2700
      pp_cxx_separate_with (pp, ',');
2705
      pp_cxx_separate_with (pp, ',');
2701
      pp->type_id (TRAIT_EXPR_TYPE2 (t));
2706
      pp->type_id (TRAIT_EXPR_TYPE2 (t));
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-base-of1.C.jj (+55 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do compile { target c++20 } }
3
4
namespace std
5
{
6
template <typename T, T v>
7
struct integral_constant
8
{
9
  static constexpr T value = v;
10
};
11
12
template <typename, typename>
13
struct is_pointer_interconvertible_base_of;
14
15
template<typename T, typename U>
16
struct is_pointer_interconvertible_base_of
17
  : public integral_constant <bool, __is_pointer_interconvertible_base_of (T, U)>
18
{
19
};
20
21
template <typename T, typename U>
22
inline constexpr bool is_pointer_interconvertible_base_of_v = __is_pointer_interconvertible_base_of (T, U);
23
}
24
25
struct A;
26
struct B { int b; };
27
struct C : virtual B { int c; };
28
struct D {};
29
struct E {};
30
struct F : public B, D, E {};
31
struct G : public D, E { int g; };
32
struct H {};
33
struct I : public G, H {};
34
struct J { int j1; private: int j2; };
35
struct K : public J {};
36
union U { int a; };
37
38
static_assert (std::is_pointer_interconvertible_base_of<A, A>::value);
39
static_assert (std::is_pointer_interconvertible_base_of_v<A, A>);
40
static_assert (std::is_pointer_interconvertible_base_of_v<const A, volatile A>);
41
static_assert (std::is_pointer_interconvertible_base_of_v<B, const B>);
42
static_assert (std::is_pointer_interconvertible_base_of_v<C, const volatile C>);
43
static_assert (!std::is_pointer_interconvertible_base_of_v<D, E>);
44
static_assert (!std::is_pointer_interconvertible_base_of_v<D, const B>);
45
static_assert (std::is_pointer_interconvertible_base_of_v<const B, F>);
46
static_assert (std::is_pointer_interconvertible_base_of_v<D, const F>);
47
static_assert (std::is_pointer_interconvertible_base_of_v<E, F>);
48
static_assert (!std::is_pointer_interconvertible_base_of_v<D, volatile G>);
49
static_assert (!std::is_pointer_interconvertible_base_of_v<const E, volatile G>);
50
static_assert (!std::is_pointer_interconvertible_base_of_v<D, I>);
51
static_assert (!std::is_pointer_interconvertible_base_of_v<const E, const I>);
52
static_assert (std::is_pointer_interconvertible_base_of_v<G, I>);
53
static_assert (std::is_pointer_interconvertible_base_of_v<H, volatile I>);
54
static_assert (!std::is_pointer_interconvertible_base_of_v<volatile J, const K>);
55
static_assert (!std::is_pointer_interconvertible_base_of_v<U, U>);
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class1.C.jj (+62 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do compile { target c++20 } }
3
4
namespace std
5
{
6
template <class S, class M>
7
constexpr bool
8
is_pointer_interconvertible_with_class (M S::*m) noexcept
9
{
10
  return __builtin_is_pointer_interconvertible_with_class (m);
11
}
12
}
13
14
struct A;
15
struct B { int b; double b2; };
16
struct C : virtual B { int c; };
17
struct D {};
18
struct E {};
19
struct F : public B, D, E {};
20
struct G : public D, E { int g; };
21
struct H {};
22
struct I : public G, H {};
23
struct J { int j1; private: int j2; public: int j3; };
24
struct K : public J {};
25
struct L : public B, D, E {};
26
struct M { D d [[no_unique_address]]; E e [[no_unique_address]]; int f; };
27
union U { int a; double b; long long c; };
28
struct V { union { int a; long b; }; int c; };
29
union X { int a; union { short b; long c; }; long long d; };
30
struct Y { void foo () {} };
31
32
static_assert (std::is_pointer_interconvertible_with_class (&B::b));
33
static_assert (!std::is_pointer_interconvertible_with_class (&B::b2));
34
static_assert (std::is_pointer_interconvertible_with_class (&C::b));
35
static_assert (std::is_pointer_interconvertible_with_class (&F::b));
36
static_assert (std::is_pointer_interconvertible_with_class<F, int> (&F::b));
37
static_assert (std::is_pointer_interconvertible_with_class (&G::g));
38
static_assert (std::is_pointer_interconvertible_with_class<G, int> (&G::g));
39
static_assert (std::is_pointer_interconvertible_with_class (&I::g));
40
static_assert (std::is_pointer_interconvertible_with_class<I, int> (&I::g));
41
static_assert (!std::is_pointer_interconvertible_with_class (&J::j1));
42
static_assert (!std::is_pointer_interconvertible_with_class (&J::j3));
43
static_assert (!std::is_pointer_interconvertible_with_class (&K::j1));
44
static_assert (!std::is_pointer_interconvertible_with_class (&K::j3));
45
static_assert (std::is_pointer_interconvertible_with_class (&L::b));
46
static_assert (std::is_pointer_interconvertible_with_class<L, int> (&L::b));
47
static_assert (std::is_pointer_interconvertible_with_class (&L::b));
48
static_assert (std::is_pointer_interconvertible_with_class (&M::d));
49
static_assert (!std::is_pointer_interconvertible_with_class (&M::e));
50
static_assert (!std::is_pointer_interconvertible_with_class (&M::f));
51
static_assert (std::is_pointer_interconvertible_with_class (&U::a));
52
static_assert (std::is_pointer_interconvertible_with_class (&U::b));
53
static_assert (std::is_pointer_interconvertible_with_class (&U::c));
54
static_assert (std::is_pointer_interconvertible_with_class (&V::a));
55
static_assert (std::is_pointer_interconvertible_with_class (&V::b));
56
static_assert (!std::is_pointer_interconvertible_with_class (&V::c));
57
static_assert (std::is_pointer_interconvertible_with_class (&X::a));
58
static_assert (std::is_pointer_interconvertible_with_class (&X::b));
59
static_assert (std::is_pointer_interconvertible_with_class (&X::c));
60
static_assert (std::is_pointer_interconvertible_with_class (&X::d));
61
static_assert (!std::is_pointer_interconvertible_with_class ((int B::*) nullptr));
62
static_assert (!std::is_pointer_interconvertible_with_class (&Y::foo));
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class2.C.jj (+128 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do run { target c++20 } }
3
4
namespace std
5
{
6
template <class S, class M>
7
constexpr bool
8
is_pointer_interconvertible_with_class (M S::*m) noexcept
9
{
10
  return __builtin_is_pointer_interconvertible_with_class (m);
11
}
12
}
13
14
struct A;
15
struct B { int b; double b2; };
16
struct C : virtual B { int c; };
17
struct D {};
18
struct E {};
19
struct F : public B, D, E {};
20
struct G : public D, E { int g; };
21
struct H {};
22
struct I : public G, H {};
23
struct J { int j1; private: int j2; public: int j3; };
24
struct K : public J {};
25
struct L : public B, D, E {};
26
struct M { D d [[no_unique_address]]; E e [[no_unique_address]]; int f; };
27
union U { int a; double b; long long c; };
28
struct V { union { int a; long b; }; int c; };
29
union X { int a; union { short b; long c; }; long long d; };
30
struct Y { void foo () {} };
31
32
int
33
main ()
34
{
35
  auto t1 = &B::b;
36
  if (!std::is_pointer_interconvertible_with_class (t1))
37
    __builtin_abort ();
38
  auto t2 = &B::b2;
39
  if (std::is_pointer_interconvertible_with_class (t2))
40
    __builtin_abort ();
41
  auto t3 = &C::b;
42
  if (!std::is_pointer_interconvertible_with_class (t3))
43
    __builtin_abort ();
44
  auto t4 = &F::b;
45
  if (!std::is_pointer_interconvertible_with_class (t4))
46
    __builtin_abort ();
47
  int F::*t5 = &F::b;
48
  if (!std::is_pointer_interconvertible_with_class (t5))
49
    __builtin_abort ();
50
  auto t6 = &G::g;
51
  if (!std::is_pointer_interconvertible_with_class (t6))
52
    __builtin_abort ();
53
  int G::*t7 = &G::g;
54
  if (!std::is_pointer_interconvertible_with_class (t7))
55
    __builtin_abort ();
56
  auto t8 = &I::g;
57
  if (!std::is_pointer_interconvertible_with_class (t8))
58
    __builtin_abort ();
59
  int I::*t9 = &I::g;
60
  if (!std::is_pointer_interconvertible_with_class (t9))
61
    __builtin_abort ();
62
  auto t10 = &J::j1;
63
  if (std::is_pointer_interconvertible_with_class (t10))
64
    __builtin_abort ();
65
  auto t11 = &J::j3;
66
  if (std::is_pointer_interconvertible_with_class (t11))
67
    __builtin_abort ();
68
  auto t12 = &K::j1;
69
  if (std::is_pointer_interconvertible_with_class (t12))
70
    __builtin_abort ();
71
  auto t13 = &K::j3;
72
  if (std::is_pointer_interconvertible_with_class (t13))
73
    __builtin_abort ();
74
  auto t14 = &L::b;
75
  if (!std::is_pointer_interconvertible_with_class (t14))
76
    __builtin_abort ();
77
  int L::*t15 = &L::b;
78
  if (!std::is_pointer_interconvertible_with_class (t15))
79
    __builtin_abort ();
80
  auto t16 = &L::b;
81
  if (!std::is_pointer_interconvertible_with_class (t16))
82
    __builtin_abort ();
83
  auto t17 = &M::d;
84
  if (!std::is_pointer_interconvertible_with_class (t17))
85
    __builtin_abort ();
86
  auto t18 = &M::e;
87
  if (std::is_pointer_interconvertible_with_class (t18))
88
    __builtin_abort ();
89
  auto t19 = &M::f;
90
  if (std::is_pointer_interconvertible_with_class (t19))
91
    __builtin_abort ();
92
  auto t20 = &U::a;
93
  if (!std::is_pointer_interconvertible_with_class (t20))
94
    __builtin_abort ();
95
  auto t21 = &U::b;
96
  if (!std::is_pointer_interconvertible_with_class (t21))
97
    __builtin_abort ();
98
  auto t22 = &U::c;
99
  if (!std::is_pointer_interconvertible_with_class (t22))
100
    __builtin_abort ();
101
  auto t23 = &V::a;
102
  if (!std::is_pointer_interconvertible_with_class (t23))
103
    __builtin_abort ();
104
  auto t24 = &V::b;
105
  if (!std::is_pointer_interconvertible_with_class (t24))
106
    __builtin_abort ();
107
  auto t25 = &V::c;
108
  if (std::is_pointer_interconvertible_with_class (t25))
109
    __builtin_abort ();
110
  auto t26 = &X::a;
111
  if (!std::is_pointer_interconvertible_with_class (t26))
112
    __builtin_abort ();
113
  auto t27 = &X::b;
114
  if (!std::is_pointer_interconvertible_with_class (t27))
115
    __builtin_abort ();
116
  auto t28 = &X::c;
117
  if (!std::is_pointer_interconvertible_with_class (t28))
118
    __builtin_abort ();
119
  auto t29 = &X::d;
120
  if (!std::is_pointer_interconvertible_with_class (t29))
121
    __builtin_abort ();
122
  auto t30 = (int B::*) nullptr;
123
  if (std::is_pointer_interconvertible_with_class (t30))
124
    __builtin_abort ();
125
  auto t31 = &Y::foo;
126
  if (std::is_pointer_interconvertible_with_class (t31))
127
    __builtin_abort ();
128
}
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class3.C.jj (+11 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do compile { target c++20 } }
3
4
struct A { int a; };
5
struct B;
6
7
bool a = __builtin_is_pointer_interconvertible_with_class ();			// { dg-error "needs a single argument" }
8
bool b = __builtin_is_pointer_interconvertible_with_class (&A::a, &A::a);	// { dg-error "needs a single argument" }
9
bool c = __builtin_is_pointer_interconvertible_with_class (1);			// { dg-error "argument is not pointer to member" }
10
bool d = __builtin_is_pointer_interconvertible_with_class (1.0);		// { dg-error "argument is not pointer to member" }
11
bool e = __builtin_is_pointer_interconvertible_with_class ((int B::*) nullptr);	// { dg-error "invalid use of incomplete type" }
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class4.C.jj (+24 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do compile { target c++20 } }
3
// { dg-options "" }
4
5
namespace std
6
{
7
template <class S, class M>
8
constexpr bool
9
is_pointer_interconvertible_with_class (M S::*m) noexcept
10
{
11
  return __builtin_is_pointer_interconvertible_with_class (m);
12
}
13
}
14
15
struct W { struct { int a; long b; }; int c; };
16
union X { int a; struct { short b; long c; }; long long d; };
17
18
static_assert (std::is_pointer_interconvertible_with_class (&W::a));
19
static_assert (!std::is_pointer_interconvertible_with_class (&W::b));
20
static_assert (!std::is_pointer_interconvertible_with_class (&W::c));
21
static_assert (std::is_pointer_interconvertible_with_class (&X::a));
22
static_assert (std::is_pointer_interconvertible_with_class (&X::b));
23
static_assert (!std::is_pointer_interconvertible_with_class (&X::c));
24
static_assert (std::is_pointer_interconvertible_with_class (&X::d));
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class5.C.jj (+42 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do run { target c++20 } }
3
// { dg-options "" }
4
5
namespace std
6
{
7
template <class S, class M>
8
constexpr bool
9
is_pointer_interconvertible_with_class (M S::*m) noexcept
10
{
11
  return __builtin_is_pointer_interconvertible_with_class (m);
12
}
13
}
14
15
struct W { struct { int a; long b; }; int c; };
16
union X { int a; struct { short b; long c; }; long long d; };
17
18
int
19
main ()
20
{
21
  auto t1 = &W::a;
22
  if (!std::is_pointer_interconvertible_with_class (t1))
23
    __builtin_abort ();
24
  auto t2 = &W::b;
25
  if (std::is_pointer_interconvertible_with_class (t2))
26
    __builtin_abort ();
27
  auto t3 = &W::c;
28
  if (std::is_pointer_interconvertible_with_class (t3))
29
    __builtin_abort ();
30
  auto t4 = &X::a;
31
  if (!std::is_pointer_interconvertible_with_class (t4))
32
    __builtin_abort ();
33
  auto t5 = &X::b;
34
  if (!std::is_pointer_interconvertible_with_class (t5))
35
    __builtin_abort ();
36
  auto t6 = &X::c;
37
  if (std::is_pointer_interconvertible_with_class (t6))
38
    __builtin_abort ();
39
  auto t7 = &X::d;
40
  if (!std::is_pointer_interconvertible_with_class (t7))
41
    __builtin_abort ();
42
}
(-)gcc/testsuite/g++.dg/cpp2a/is-pointer-interconvertible-with-class6.C.jj (+19 lines)
Line 0 Link Here
1
// P0466R5
2
// { dg-do compile { target c++20 } }
3
4
namespace std
5
{
6
template <class S, class M>
7
constexpr bool
8
is_pointer_interconvertible_with_class (M S::*m) noexcept
9
{
10
  return __builtin_is_pointer_interconvertible_with_class (m);
11
}
12
}
13
14
struct A { int a; };
15
16
double A::*a = nullptr;
17
constexpr double A::*b = nullptr;
18
constexpr auto c = std::is_pointer_interconvertible_with_class (a);	// { dg-error "is not usable in a constant expression" }
19
constexpr auto d = std::is_pointer_interconvertible_with_class (b);

Return to bug 101539