llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.39k stars 12.15k forks source link

False positive: Uninitialized value used after std::seed_seq::generate #40644

Open Flamefire opened 5 years ago

Flamefire commented 5 years ago
Bugzilla Link 41299
Version unspecified
OS Linux
CC @devincoughlin,@EugeneZelenko

Extended Description

I implemented a custom PRNG according to the standard which uses a 32-Bit value as the seed. Hence I've implemented the seed(seedSeq) function as follows:

{ unsigned seedVal; seedSeq.generate(&seedVal, (&seedVal) + 1); seed(seedVal); }

However clang-tidy warns about using an uninitialized value for the call to seed at the bottom.

Relevant output:

[...] /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3279:4: note: Value assigned to 'r1' r1 = detail::mod<_Type, [...] /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3290:4: note: Uninitialized value stored to 'seedVal' begin[(k + p) % n] += __r1;

There is nothing else that looks suspicious. My guess is that as clang-tidy cannot deduce that n = __end - __begin in this case equals one it messes up the rest.

EugeneZelenko commented 5 years ago

All checks with names started from clang-analyzer are implemented in Clang Static Analyzer, not Clang-tidy. Later just use them.

Flamefire commented 5 years ago

Sure:

clang-tidy-8 -p . -checks="-,clang-analyzer-core.CallAndMessage" main.cpp 1 warning generated. /home/alex/Schreibtisch/cmakeTest/main.cpp:10:5: warning: 1st function call argument is an uninitialized value [clang-analyzer-core.CallAndMessage] seed(seedVal); ^ /home/alex/Schreibtisch/cmakeTest/main.cpp:15:3: note: Calling 'MySeed' MySeed(seedSeq); ^ /home/alex/Schreibtisch/cmakeTest/main.cpp:9:5: note: Calling 'seed_seq::generate' seedSeq.generate(&seedVal, (&seedVal) + 1); ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3257:7: note: Taking false branch if (begin == end) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3260:7: note: Calling 'fill<unsigned int , unsigned int>' std::fill(begin, end, _Type(0x8b8b8b8bu)); ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:731:21: note: Calling 'niter_base<unsigned int *>' std::__fill_a(std::niter_base(first), std::niter_base(last), ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:731:21: note: Returning from 'niter_base<unsigned int >' /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:731:7: note: Calling '__fill_a<unsigned int , unsigned int>' std::fill_a(std::__niter_base(first), std::niter_base(last), ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:695:7: note: Loop condition is true. Entering loop body for (; first != last; ++first) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:695:7: note: Loop condition is false. Execution continues on line 695 /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_algobase.h:731:7: note: Returning from '__fill_a<unsigned int *, unsigned int>' std::fill_a(std::niter_base(first), std::niter_base(last), ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3260:7: note: Returning from 'fill<unsigned int , unsigned int>' std::fill(begin, end, _Type(0x8b8b8b8bu)); ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3264:27: note: Assuming 'n' is >= 623 const size_t t = (n >= 623) ? 11 ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3264:26: note: '?' condition is true const size_t t = (n >= 623) ? 11 ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3273:28: note: Assuming 'k' is < 'm' for (size_t k = 0; k < m; ++k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3273:7: note: Loop condition is true. Entering loop body for (size_t k = 0; k < m; ++k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3279:11: note: Calling 'mod<unsigned int, 0, 1, 0>' r1 = detail::mod<_Type, ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:147:16: note: Calling '_Mod::calc' { return _Mod<_Tp, m, a, c>::calc(x); } ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:137:4: note: 'res' initialized here _Tp res = a x + c; ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:138:4: note: Taking false branch if (m) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:140:4: note: Returning value (loaded from 'res') return res; ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:147:16: note: Returning from '_Mod::calc' { return _Mod<_Tp, m, a, c>::calc(x); } ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.h:147:9: note: Returning value { return _Mod<_Tp, m, a, c>::calc(x); } ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3279:11: note: Returning from 'mod<unsigned int, 0, 1, 0>' r1 = detail::mod<_Type, ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3279:4: note: Value assigned to 'r1' r1 = detail::mod<_Type, ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3282:4: note: Taking true branch if (k == 0) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3290:4: note: Uninitialized value stored to 'seedVal' begin[(k + p) % n] += __r1; ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3273:28: note: Assuming 'k' is >= '__m' for (size_t k = 0; k < m; ++k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3273:7: note: Loop condition is false. Execution continues on line 3295 for (size_t k = 0; k < m; ++k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3295:30: note: Assuming the condition is false for (size_t k = m; k < m + n; ++k) ^ /usr/bin/../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/random.tcc:3295:7: note: Loop condition is false. Execution continues on line 3295 for (size_t k = m; k < m + n; ++k) ^ /home/alex/Schreibtisch/cmakeTest/main.cpp:9:5: note: Returning from 'seed_seq::generate' seedSeq.generate(&seedVal, (&seedVal) + 1); ^ /home/alex/Schreibtisch/cmakeTest/main.cpp:10:5: note: 1st function call argument is an uninitialized value seed(seedVal);

Input file:

include

extern void seed(unsigned);

template inline void MySeed(T_SeedSeq& seedSeq) { unsigned seedVal; seedSeq.generate(&seedVal, (&seedVal) + 1); seed(seedVal); }

int main(){ std::seed_seq seedSeq({1,2,3}); MySeed(seedSeq); }

EugeneZelenko commented 5 years ago

Could you please provide full message with check name?

Flamefire commented 5 years ago

assigned to @devincoughlin