microsoft / vscode-cpptools

Official repository for the Microsoft C/C++ extension for VS Code.
Other
5.46k stars 1.53k forks source link

VSCode reports 'converstion from "x" to "y" is invalid in constant-expression evalution', yet code builds fine #2111

Open sylveon opened 6 years ago

sylveon commented 6 years ago

Type: LanguageService

Describe the bug

To Reproduce Steps to reproduce the behavior: (The default C++ properties were used)

  1. Clone the following gist: https://gist.github.com/sylveon/b63621297d566d06ab38bd5586eca0ed
  2. Open it in vscode
  3. Open main.cpp
  4. See red squiggles on CalculateHueGradient() call
  5. When hovering, you can read expression must have a constant value -- conversion from "float" to "unsigned short" is invalid in constant-expression evaluation

Expected behavior No error, like msvc and clang do while building the snippet:

C:\Users\Charles\Git\TranslucentTB>cl test.cpp /EHsc
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26430 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 14.14.26430.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
test.obj
C:\Users\Charles\Git\TranslucentTB>clang-cl --version
clang version 6.0.0 (tags/RELEASE_600/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin

C:\Users\Charles\Git\TranslucentTB>clang-cl /EHsc test.cpp
(no output, meaning a successful compilation)
sean-mcmanus commented 6 years ago

What's the definition of SColour? I couldn't get the bug repro with my made up version:

struct SColour
{
    int h, r, g, b;
    int s;
    int v;
    constexpr void UpdateRGB() {}
};
sylveon commented 6 years ago

The SColour.hpp header, which has all information needed, is included in the gist.

sean-mcmanus commented 6 years ago

Oh, I didn't see it before. Thanks for the repro -- it repros in VS 2017 too so I'll let the team know.

Adding the typecast below is a "workaround" -- I don't know for sure if the error is valid or not according to the language spec (conversion from float to unsigned short is a data loss warning, but compiles as you've shown above):

tempcol.h = tempcol.h - (unsigned short)step;

Also, I was able to simply the repro to just:

constexpr const float cfunc()
{
    unsigned short h = 0;
    const float step = 359;
    h = h - step;
    return (float)h;
}

inline const auto &func()
{
    static constexpr auto value = cfunc();
    return value;
}

int main2()
{
    return (int)func();
}
sylveon commented 6 years ago

I tried getting a minimal repro but apparently I didn't try hard enough 😅

sylveon commented 6 years ago

Figured it out: implicit narrowing in constexpr is not allowed. The IntelliSense engine is in the right, the compiler is in the wrong @sean-mcmanus.

Your cast makes the error disappear, because the narrowing is now explicit, and the constexpr becomes valid.

sean-mcmanus commented 6 years ago

Our IntelliSense parser is actually supposed mimic the C/C++ language errors that exist in particular versions of compilers, so from our perspective it's still a bug. But making your code conform to the standard is probably a good idea too, in case future compilers fix the error.

Colengms commented 4 years ago

I couldn't find a VS bug on this, and it still repro's in VS 2019. I opened a new bug for it: https://developercommunity.visualstudio.com/content/problem/900784/intellisense-squiggle-on-use-of-a-constexpr-functi.html

bobbrow commented 2 days ago

The developer community ticket was resolved as a duplicate of another issue which took a different turn. I'll re-report this. I changed the repro a little to be a little closer to the original and avoid underflow. https://godbolt.org/z/bG48YdTK4

internal ticket (2256548)