<div dir="ltr">Hello,<div><br></div><div>I am not sure about the semantic (if any) of returns_twice and noreturn attributes.</div><div><br></div><div><font face="monospace, monospace">int fork() __attribute__((returns_twice));</font></div><div><font face="monospace, monospace">void join(int) __attribute__((noreturn));</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">int f(int n) {</font></div><div><font face="monospace, monospace">  int t = fork();</font></div><div><font face="monospace, monospace">  n++;</font></div><div><font face="monospace, monospace">  if (t != 0)</font></div><div><font face="monospace, monospace">    join(t);</font></div><div><font face="monospace, monospace">  return n;</font></div><div><font face="monospace, monospace">}</font></div><div><br></div><div>Produces the following LLVM IR:</div><div><br></div><div><div><font face="monospace, monospace">; Function Attrs: nounwind uwtable</font></div><div><font face="monospace, monospace">define i32 @f(i32 %n) local_unnamed_addr #0 {</font></div><div><font face="monospace, monospace">entry:</font></div><div><font face="monospace, monospace">  %call = call i32 (...) @fork() #3</font></div><div><font face="monospace, monospace">  %cmp = icmp eq i32 %call, 0</font></div><div><font face="monospace, monospace">  br i1 %cmp, label %if.end, label %if.then</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">if.then:                                          ; preds = %entry</font></div><div><font face="monospace, monospace">  call void @join(i32 %call) #4</font></div><div><font face="monospace, monospace">  unreachable</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">if.end:                                           ; preds = %entry</font></div><div><font face="monospace, monospace">  %inc = add nsw i32 %n, 1</font></div><div><font face="monospace, monospace">  ret i32 %inc</font></div><div><font face="monospace, monospace">}</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">; Function Attrs: returns_twice</font></div><div><font face="monospace, monospace">declare i32 @fork(...) local_unnamed_addr #1</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">; Function Attrs: noreturn</font></div><div><font face="monospace, monospace">declare void @join(i32) local_unnamed_addr #2</font></div><div><br></div><div>Where the n++ has been moved after the if, is that legal?</div><div><br></div><div>Also, technically, f could also returns_twice or noreturn (depending on the return values of fork).</div><div><br></div><div>So my question is: do they have semantic or they are only "clues" for heuristic purposes?</div><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><b>Alexandre Isoard</b><br></div></div>
</div></div>