__builtin_choose_expr

Andy Gibbs andyg1001@hotmail.co.uk
Mon Oct 10 15:00:00 GMT 2011


Hi,

There is a very useful feature in gcc, namely __builtin_choose_expr, which 
isn't available in g++.  I expect that this is simply down to the fact that 
it had a very obvious use relating to overloading functions in C which isn't 
necessary in C++, and therefore it simply didn't get implemented.

Assuming that this was indeed the only reason, I thought rather than 
whinging that this wasn't available in C++, I'd have a go at implementing 
it.

Attached below, therefore, is a simple patch to GCC 4.6.1 which implements 
__builtin_choose_expr for C++.  From my testing, it "seems to work fine", 
but I'm afraid this is my first time hacking GCC, so I would be very 
grateful if someone much more knowledgeable than me could check over my 
patch (it should be very easy to follow) to see whether my approach is valid 
or not.

If it seems to people that this is a useful / suitable addition to GCC 
generally, then I would be happy to supplement my patch with test-cases and 
proper documentation and see whether it can be merged into the GCC trunk. 
Obviously I have uses for this feature, but I don't know whether it has a 
broader appeal!  ;o)

Thanks

Andy

--- <snip> ---

--- gcc-4.6.1-orig/gcc/c-family/c-common.c
+++ gcc-4.6.1/gcc/c-family/c-common.c
@@ -420,7 +420,7 @@ const struct c_common_resword c_common_r
   { "__asm__",  RID_ASM, 0 },
   { "__attribute", RID_ATTRIBUTE, 0 },
   { "__attribute__", RID_ATTRIBUTE, 0 },
-  { "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
+  { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 },
   { "__builtin_offsetof", RID_OFFSETOF, 0 },
   { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, D_CONLY },
   { "__builtin_va_arg", RID_VA_ARG, 0 },
--- gcc-4.6.1-orig/gcc/cp/parser.c
+++ gcc-4.6.1/gcc/cp/parser.c
@@ -1837,6 +1837,8 @@ static tree cp_parser_expression
   (cp_parser *, bool, cp_id_kind *);
 static tree cp_parser_constant_expression
   (cp_parser *, bool, bool *);
+static tree cp_parser_builtin_choose_expr
+  (cp_parser *);
 static tree cp_parser_builtin_offsetof
   (cp_parser *);
 static tree cp_parser_lambda_expression
@@ -3850,6 +3852,9 @@ cp_parser_primary_expression (cp_parser
  case RID_OFFSETOF:
    return cp_parser_builtin_offsetof (parser);

+ case RID_CHOOSE_EXPR:
+   return cp_parser_builtin_choose_expr (parser);
+
  case RID_HAS_NOTHROW_ASSIGN:
  case RID_HAS_NOTHROW_CONSTRUCTOR:
  case RID_HAS_NOTHROW_COPY:
@@ -7403,6 +7408,43 @@ cp_parser_builtin_offsetof (cp_parser *p
   return expr;
 }

+/* Parse __builtin_choose_expr.
+
+     __builtin_choose_expr ( constant-expression ,
+        assignment-expression ,
+        assignment-expression )  */
+
+static tree
+cp_parser_builtin_choose_expr (cp_parser *parser)
+{
+  tree condition, expr_true, expr_false;
+
+  /* Consume the "__builtin_choose_expr" token.  */
+  cp_lexer_consume_token (parser->lexer);
+
+  /* Parse expressions. */
+  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
+  condition = cp_parser_constant_expression (parser, false, NULL);
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  expr_true = cp_parser_assignment_expression (parser, false, NULL);
+  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
+  expr_false = cp_parser_assignment_expression (parser, false, NULL);
+  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
+ cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
+
+  /* Fold the condition expression and convert it to a boolean value. */
+  condition = fold_non_dependent_expr (condition);
+  condition = cp_convert (boolean_type_node, condition);
+  condition = maybe_constant_value (condition);
+
+  if (TREE_CODE (condition) == INTEGER_CST)
+ return integer_zerop (condition) ? expr_false : expr_true;
+
+  error ("non-constant condition for %<__builtin_choose_expr%>");
+  cxx_constant_value (condition);
+  return error_mark_node;
+}
+
 /* Parse a trait expression.

    Returns a representation of the expression, the underlying type



More information about the Gcc-help mailing list