summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/noncompile/label-1.c
blob: 58d212f967516b1f50ce344402d8cbede35691b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* Test various diagnostics of ill-formed constructs involving labels.  */
/* { dg-do compile } */
/* { dg-options "-Wunused" } */

extern void dummy(void);

/* labels must be defined */
void a(void)
{
  goto l;   /* { dg-error "used but not defined" "no label" } */
}

/* warnings for labels defined but not used, or declared but not defined */
void b(void)
{
  __label__ l;
 l:  /* { dg-warning "defined but not used"  "no goto 1" } */
 m:  /* { dg-warning "defined but not used"  "no goto 2" } */
  dummy();
}

void c(void)
{
  __label__ l;  /* { dg-warning "declared but not defined" "only __label__" } */
  dummy();
}

/* can't have two labels with the same name in the same function */
void d(void)
{
 l: dummy();  /* { dg-message "note: previous definition" "prev def same scope" } */
 l: dummy();  /* { dg-error "duplicate label" "dup label same scope" } */
 goto l;
}

/* even at different scopes */
void e(void)
{
 l: dummy();	/* { dg-message "note: previous definition"  "prev def diff scope" } */
  {
  l: dummy();	/* { dg-error "duplicate label" "dup label diff scope" } */
  }
  goto l;
}

/* but, with __label__, you can */
void f(void)
{
 l: dummy();
  {
    __label__ l;
    l: dummy();	  /* { dg-warning "defined but not used" "unused shadow 1" } */
  };
  goto l;  /* this reaches the outer l */
}

/* a __label__ is not visible outside its scope */
void g(void)
{
  dummy();
  {
    __label__ l;
    l: dummy();
    goto l;
  }
  goto l;  /* { dg-error "used but not defined" "label ref out of scope" } */
}

/* __label__ can appear at top level of a function, too...
   ... but doesn't provide a definition of the label */
void h(void)
{
  __label__ l;
  dummy ();

  goto l;  /* { dg-error "used but not defined" "used, only __label__" } */
}

/* A nested function may not goto a label outside itself  */
void i(void)
{
  auto void nest(void);

 l: nest();
  
  void nest(void)
    {
      goto l;  /* { dg-error "used but not defined" "nest use outer label" } */
    }

  goto l; /* reaches the outer l */
}

/* which means that a nested function may have its own label with the
   same name as the outer function */
void j(void)
{
  auto void nest(void);

 l: nest();
  
  void nest(void)
    {
    l: dummy(); /* { dg-warning "defined but not used" "nest label same name" } */
    }

  goto l; /* reaches the outer l */
}

/* and, turnabout, an outer function may not goto a label in a nested
   function */
void k(void)
{
  void nest(void)
  {
  l: dummy();  /* { dg-warning "defined but not used" "outer use nest label" } */
  }

  goto l; /* { dg-error "used but not defined" "outer use nest label" } */
  nest();
}

/* not even with __label__ */
void l(void)
{
  void nest(void)
  {
    __label__ l;
  l: dummy(); /* { dg-warning "defined but not used" "outer use nest __label__" } */
  }

  goto l; /* { dg-error "used but not defined" "outer use nest __label__" } */
  nest();
}


/* but if the outer label is declared with __label__, then a nested
   function can goto that label (accomplishing a longjmp) */
void m(void)
{
  __label__ l;
  void nest(void) { goto l; }
  nest();
  dummy();
 l:;
}

/* and that means the nested function cannot have its own label with
   the same name as an outer label declared with __label__ */

void n(void)
{
  __label__ l; /* { dg-message "note: previous declaration" "outer label decl" } */
  void nest(void)
    {
    l: goto l;  /* { dg-error "duplicate label" "inner label defn" } */
    }

 l:
  nest();
}

/* unless the nested function uses __label__ too!  */
void o(void)
{
  __label__ l;
  void nest(void)
    {
      __label__ l;
    l: goto l;
    }

 l: goto l;
 nest();
}