[cfe-dev] clang++: Handling of division by zero in array bounds

Stephan Bergmann via cfe-dev cfe-dev at lists.llvm.org
Wed Nov 9 02:34:48 PST 2016


On 11/09/2016 11:12 AM, James Dennett wrote:
> On Wed, Nov 9, 2016 at 2:06 AM, David Chisnall via cfe-dev
> <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>
>     On 9 Nov 2016, at 07:55, Stephan Bergmann via cfe-dev
>     <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>     >
>     > What I observe with various versions of Clang:
>     >
>     >> $ cat test.cc
>     >> #include <iostream>
>     >> int main() {
>     >>    char a[1/0];
>     >>    std::cout << sizeof a << '\n';
>     >> }
>     >>
>     >> $ clang++ -Weverything test.cc
>     >> test.cc:3:11: warning: variable length arrays are a C99 feature
>     >>      [-Wvla-extension]
>     >>    char a[1/0];
>     >>          ^
>     >> test.cc:3:11: warning: variable length array used [-Wvla]
>     >> 2 warnings generated.
>     >>
>     >> $ ./a.out
>     >> 0
>     >
>     > Is there a specific reason to not emit a warning/error about the undefined behavior in evaluating the constant bounds expression, 1/0?
>
>     I believe that the issue here is that 1/0 is *not* a constant
>     expression, it is undefined behaviour (typically, run-time trap).
>     We probably should have a special return value for attempting to
>     evaluate something that should be an ICE and finding that the result
>     is undefined, which would allow this to become a more helpful error
>     along the lines of ‘array length is an undefined value, this will
>     abort at run time’.
>
>     Currently, I believe that the undefined value is simply marked as
>     something that can not be evaluated at compile time and so this is
>     equivalent to:
>
>     int foo(int d)
>     {
>       char a[1/d];
>       std::cout << sizeof a << '\n';
>     }
>
>     This is valid code when d > 0, but if d == 0 it will likely trap.
>
>     David
>
>
> A constant expression that would give undefined behavior is ill-formed,

No, 1/0 is not a core constant expression, because evaluating it "would 
have undefined behavior as spedified in Clauses 1 through 16" 
([expr.const]), so is not a constant expression.  So apparently the 
non-standard C99 vla extension kicks in as David explained.  (Question 
is whether that extension can be disabled?)

> and the compiler is required to issue a diagnostic.  It does, by
> default, but the diagnostic is misleading and doesn't identify why the
> code is ill-formed.  So it's not formally a violation of the C++
> standard, but it's not a good error message.  Compiling the code and
> acting as if 1/0 was 0 is also fairly dubious (though again, not a
> violation of the C++ standard, which only requires a diagnostic and
> never forbids producing an executable).




More information about the cfe-dev mailing list