gcc_attribute_var.c revision 1.4
11.4Srillig/*	$NetBSD: gcc_attribute_var.c,v 1.4 2021/08/11 05:08:35 rillig Exp $	*/
21.1Srillig# 3 "gcc_attribute_var.c"
31.1Srillig
41.1Srillig/*
51.1Srillig * Tests for the GCC __attribute__ for variables.
61.1Srillig *
71.1Srillig * https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html
81.1Srillig */
91.1Srillig
101.1Srilligvoid
111.1Srilligwrite_to_page(unsigned index, char ch)
121.1Srillig{
131.1Srillig	static char page[4096]
141.1Srillig	    __attribute__((__aligned__(4096)));
151.1Srillig
161.1Srillig	page[index] = ch;
171.1Srillig}
181.1Srillig
191.1Srilligvoid
201.1Srilligplacement(
211.1Srillig    __attribute__((__deprecated__)) int before,
221.1Srillig    int __attribute__((__deprecated__)) between,
231.1Srillig    int after __attribute__((__deprecated__))
241.1Srillig);
251.1Srillig
261.2Srilligvoid println(void);
271.2Srillig
281.2Srillig/*
291.2Srillig * Since cgram.y 1.294 from 2021-07-10, lint did not accept declarations that
301.2Srillig * started with __attribute__, due to a newly and accidentally introduced
311.2Srillig * shift/reduce conflict in the grammar.
321.2Srillig *
331.2Srillig * A GCC extension allows statement of the form __attribute__((fallthrough)),
341.2Srillig * thus starting with __attribute__.  This is the 'shift' in the conflict.
351.2Srillig * The 'reduce' in the conflict was begin_type.
361.2Srillig *
371.2Srillig * Before cgram 1.294, the gcc_attribute was placed outside the pair of
381.2Srillig * begin_type/end_type, exactly to resolve this conflict.
391.2Srillig *
401.2Srillig * Conceptually, it made sense to put the __attribute__((unused)) between
411.2Srillig * begin_type and end_type, to make it part of the declaration-specifiers.
421.2Srillig * This change introduced the hidden conflict though.
431.2Srillig *
441.2Srillig * Interestingly, the number of shift/reduce conflicts did not change in
451.2Srillig * cgram 1.294, the conflicts were just resolved differently than before.
461.2Srillig *
471.2Srillig * To prevent this from happening again, make sure that declarations as well
481.2Srillig * as statements can start with gcc_attribute.
491.2Srillig */
501.2Srilligvoid
511.2Srilligambiguity_for_attribute(void)
521.2Srillig{
531.2Srillig	__attribute__((unused)) _Bool var1;
541.2Srillig
551.2Srillig	switch (1) {
561.2Srillig	case 1:
571.2Srillig		println();
581.3Srillig		/* expect+1: warning: 'var2' unused in function 'ambiguity_for_attribute' [192] */
591.2Srillig		__attribute__((unused)) _Bool var2;
601.2Srillig		__attribute__((fallthrough));
611.2Srillig		case 2:
621.2Srillig			println();
631.2Srillig	}
641.2Srillig}
651.2Srillig
661.4Srilligvoid
671.4Srilligattribute_after_array_brackets(
681.4Srillig    /* FIXME: GCC accepts this */
691.4Srillig    /* expect+1: error: syntax error '__attribute__' [249] */
701.4Srillig    const char *argv[] __attribute__((__unused__))
711.4Srillig)
721.4Srillig{
731.4Srillig}
741.4Srillig
751.1Srillig/* just to trigger _some_ error, to keep the .exp file */
761.1Srillig/* expect+1: error: syntax error 'syntax_error' [249] */
771.1Srillig__attribute__((syntax_error));
78