Skip to content

<algorithm>: fill fails to compile with volatile pointer inputs #1183

@Ryan-rsm-McKenzie

Description

@Ryan-rsm-McKenzie

Describe the bug
Passing volatile pointers to fill with arguments that satisfy _Fill_memset_is_safe will fail to compile, as that branch calls memset which cannot take volatile pointers.

Command-line test case

E:\Temp>type repro.cpp
#include <cstdlib>
#include <iostream>
#include <algorithm>

void memzero(void* a_dst, std::size_t a_size)
{
    const auto     beg = static_cast<volatile char*>(a_dst);
    const auto     end = static_cast<volatile char*>(a_dst) + a_size;
    constexpr char val = 0;
    std::fill(beg, end, val);
}

int main()
{
    int num = 42;

    std::cout << num << '\n';
    memzero(&num, sizeof(num));
    std::cout << num << '\n';
}

E:\Temp>cl /EHsc /W4 /WX .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.28.29115 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

repro.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29115\include\xutility(4717): error C2664: 'void *memset(void *,int,size_t)': cannot convert argument 1 from '_FwdIt' to 'void *'
        with
        [
            _FwdIt=volatile char *
        ]
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29115\include\xutility(4717): note: Conversion loses qualifiers
C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.28.29115\include\vcruntime_string.h(63): note: see declaration of 'memset'
.\repro.cpp(10): note: see reference to function template instantiation 'void std::fill<volatile char*,char>(const _FwdIt,const _FwdIt,const _Ty &)' being compiled
        with
        [
            _FwdIt=volatile char *,
            _Ty=char
        ]

Expected behavior
The program should compile.

STL version

Microsoft Visual Studio Community 2019 Preview
Version 16.8.0 Preview 1.0

Additional context
Both GCC and Clang can compile this example, here's a godbolt link.

It will actually compile if you use std::fill(beg, end, 0); presumably because _Ty is now int and _Fill_memset_is_safe evaluates to false.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions