Home | History | Annotate | Line # | Download | only in lint1
expr_precedence.c revision 1.6
      1 /*	$NetBSD: expr_precedence.c,v 1.6 2021/07/26 18:06:43 rillig Exp $	*/
      2 # 3 "expr_precedence.c"
      3 
      4 /*
      5  * Tests for the precedence among operators.
      6  */
      7 
      8 int var;
      9 
     10 /*
     11  * An initializer needs an assignment-expression; the comma must be
     12  * interpreted as a separator, not an operator.
     13  */
     14 /* expect+1: error: syntax error '4' [249] */
     15 int init_error = 3, 4;
     16 
     17 /* expect+1: error: non-constant initializer [177] */
     18 int init_syntactically_ok = var = 1 ? 2 : 3;
     19 
     20 /*
     21  * The arguments of __attribute__ must be constant-expression, as assignments
     22  * don't make sense at that point.
     23  */
     24 void __attribute__((format(printf,
     25     /*
     26      * Inside of __attribute__((...)), symbol lookup works differently.  For
     27      * example, 'printf' is a keyword, and since all arguments to
     28      * __attribute__ are constant expressions, looking up global variables
     29      * would not make sense.  Therefore, 'var' is undefined.
     30      *
     31      * See lex.c, function 'search', keyword 'attron'.
     32      */
     33     /* expect+2: error: 'var' undefined [99] */
     34     /* expect+1: syntax error '=' [249] */
     35     var = 1,
     36     /* Syntactically ok, must be a constant expression though. */
     37     var > 0 ? 2 : 1)))
     38 my_printf(const char *, ...);
     39 
     40 void
     41 assignment_associativity(int arg)
     42 {
     43 	int left, right;
     44 
     45 	/*
     46 	 * Assignments are right-associative.  If they were left-associative,
     47 	 * the result of (left = right) would be an rvalue, resulting in this
     48 	 * error message: 'left operand of '=' must be lvalue [114]'.
     49 	 */
     50 	left = right = arg;
     51 
     52 	left = arg;
     53 }
     54 
     55 void
     56 conditional_associativity(_Bool cond1, _Bool cond2, int a, int b, int c)
     57 {
     58 	/* The then-expression can be an arbitrary expression. */
     59 	var = cond1 ? cond2 ? a : b : c;
     60 	var = cond1 ? (cond2 ? a : b) : c;
     61 
     62 	/* The then-expression can even be a comma-expression. */
     63 	/* expect+1: error: syntax error ',' [249] *//* FIXME */
     64 	var = cond1 ? cond2 ? a, b : (b, a) : c;
     65 
     66 	var = cond1 ? a : cond2 ? b : c;
     67 	/*
     68 	 * In almost all programming languages, '?:' is right-associative,
     69 	 * which allows for easy chaining.
     70 	 */
     71 	var = cond1 ? a : (cond2 ? b : c);
     72 	/*
     73 	 * In PHP, '?:' is left-associative, which is rather surprising and
     74 	 * requires more parentheses to get the desired effect.
     75 	 */
     76 	var = (cond1 ? a : cond2) ? b : c;
     77 }
     78