Skip to content

Resolve syncing conflicts from FromPrivateLiveToMaster to main #4577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions docs/code-quality/c26441.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "Learn more about: Warning C26441 NO_UNNAMED_GUARDS"
title: Warning C26441
ms.date: 2/7/2023
description: "Learn more about: Warning C26441 NO_UNNAMED_GUARDS."
ms.date: 5/11/2023
f1_keywords: ["C26441", "NO_UNNAMED_GUARDS"]
helpviewer_keywords: ["C26441"]
---
Expand All @@ -19,13 +19,23 @@ The standard library provides locks to help control concurrent access to resourc

This diagnostic only analyzes the standard lock types `std::scoped_lock`, `std::unique_lock`, and `std::lock_guard`. Warning [C26444](c26444.md) covers other unnamed RAII types.

The analyzer only analyzes simple calls to constructors. More complex initializer expressions may lead to inaccurate results in the form of missed warnings. Locks passed as arguments to function calls or returned as results of function calls are ignored because the analysis tool is unable to determine if those locks are deliberately trying to protect that function call or if they should be extended. To provide similar protection for types returned by a function call, annotate them with `[[nodiscard]]`. The analyzer ignores locks created as temporaries but assigned to named references to extend their lifetime.
The analyzer only analyzes simple calls to constructors. More complex initializer expressions may lead to inaccurate results in the form of missed warnings. The analyzer ignores locks passed as arguments to function calls or returned from function calls. It's unable to determine if those locks are deliberately trying to protect that function call or if their [lifetime should be extended](https://abseil.io/tips/107). To provide similar protection for types returned by a function call, annotate them with `[[nodiscard]]`. You can also annotate constructors with `[[nodiscard]]` to avoid unnamed objects of that type:

```cpp
struct X { [[nodiscard]] X(); };

void f() {
X{}; // warning C4834
}
```

The analyzer ignores locks created as temporaries but assigned to named references to extend their lifetime.

Code analysis name: `NO_UNNAMED_GUARDS`

## Example

In this example the name of the scoped lock is missing.
In this example, the name of the scoped lock is missing.

```cpp
void print_diagnostic(std::string_view text)
Expand Down
44 changes: 20 additions & 24 deletions docs/code-quality/c26444.md
Original file line number Diff line number Diff line change
@@ -1,53 +1,49 @@
---
description: "Learn more about: Warning C26444 NO_UNNAMED_RAII_OBJECTS"
title: Warning C26444
ms.date: 01/18/2017
description: "Learn more about: Warning C26444 NO_UNNAMED_RAII_OBJECTS."
ms.date: 05/11/2023
f1_keywords: ["C26444", "NO_UNNAMED_RAII_OBJECTS"]
helpviewer_keywords: ["C26444"]
---
# Warning C26444

> Avoid unnamed objects with custom construction and destruction.
> Don't try to declare a local variable with no name (es.84).

## C++ Core Guidelines

[ES.84: Don't (try to) declare a local variable with no name](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-noname)
[ES.84: Don't (try to) declare a local variable with no name](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-noname)

Unnamed (that is, temporary) objects with non-trivial behavior may point to either (a) inefficient code that allocates and immediately throws away resources or (b) to the code that unintentionally ignores non-primitive data. Sometimes it may also indicate plainly wrong declaration.
An unnamed variable declaration creates a temporary object that is discarded at the end of the statement. Such temporary objects with nontrivial behavior may point to either inefficient code that allocates and immediately throws away resources or to the code that unintentionally ignores nonprimitive data. Sometimes it may also indicate plainly wrong declaration.

## Notes
## Remarks

- This rule detects types with non-deleted destructors. Keep in mind that destructors can be compiler generated.
- The warning can flag code that isn't compiler generated and that invokes either a non-default constructor of a RAII type or a function that returns an object of such type. This warning helps to detect ignored call results in addition to wrong declarations.
- This rule detects types with a hand-written destructor or a compiler-generated destructor that transitively calls a hand-written destructor.
- This rule can flag code that invokes a nontrivial constructor of a RAII type.
- The logic skips temporaries if they're used in higher-level expressions. One example is temporaries that are passed as arguments or used to invoke a function.
- The standard library implementation may have different versions of destruction logic for some types (for example, containers). This can produce noisy warnings on debug builds because it's customary to ignore iterators returned from calls like [`std::vector::insert`](../standard-library/vector-class.md#insert). While such warnings aren't actionable in most cases, they're legitimate in pointing to the place where some non-obvious work is done in temporary objects.

Code analysis name: `NO_UNNAMED_RAII_OBJECTS`

## Example: Ignored call result
## Examples

```cpp
std::string ToTraceMessage(State &state);
void SaveState(State &state)
struct A { A(int i); ~A(); };
void Foo()
{
// ...
ToTraceMessage(state); // C26444, should we do something with the result of this call?
A{42}; // warning C26444: Don't try to declare a local variable with no name (es.84).
}
```

Example: Ignored call result - fixed.
std::cerr << ToTraceMessage(state);
To fix the issue, convert the temporary object to a local.

Example: Unexpected lifetime.
void SplitCache()
```cpp
struct A { A(int i); ~A(); };
void Foo()
{
gsl::finally([] { RestoreCache(); }); // C26444, RestoreCache is invoked immediately!
//...
A guard{42}; // OK.
}

Example: Unexpected lifetime - fixed.
const auto _ = gsl::finally([] { RestoreCache(); });
```

## See also

[ES.84: Don't (try to) declare a local variable with no name](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
[C26441](C26441.md)\
[ES.84: Don't (try to) declare a local variable with no name](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-noname)
18 changes: 13 additions & 5 deletions docs/code-quality/c26449.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
---
description: "Learn more about: Warning C26449 NO_SPAN_FROM_TEMPORARY"
title: Warning C26449
ms.date: 03/22/2018
description: "Learn more about: Warning C26449 NO_SPAN_FROM_TEMPORARY."
ms.date: 05/11/2023
f1_keywords: ["C26449", "NO_SPAN_FROM_TEMPORARY"]
helpviewer_keywords: ["C26449"]
---
# Warning C26449

> `gsl::span` or `std::string_view` created from a temporary will be invalid when the temporary is invalidated (gsl.view)

C++ Core Guidelines: [GSL.view: Views](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#gslview-views).
C++ Core Guidelines: [GSL.view: Views](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#SS-views).

Spans and views are convenient and lightweight types that allow you to reference memory buffers. But they must be used carefully: while their interface looks similar to standard containers, their behavior is more like the behavior of pointers and references. They don't own data and must never be constructed from temporary buffers. This check focuses on cases where source data is temporary, while a span or view isn't. There's another check that handles a slightly different scenario involving span references: [C26445 NO_SPAN_REF](c26445.md). Both rules can help to avoid subtle but dangerous mistakes made when legacy code gets modernized and adopts spans or views.
Spans and views are convenient and lightweight types that allow you to reference memory buffers. But they must be used carefully: while their interface looks similar to standard containers, their behavior is more like the behavior of pointers and references. They don't own data and must never be constructed from temporary buffers. This check focuses on cases where source data is temporary, while a span or view isn't. This rule can help to avoid subtle but dangerous mistakes made when legacy code gets modernized and adopts spans or views. There's another check that handles a slightly different scenario involving span references: [C26445 NO_SPAN_REF](c26445.md).

Consider using [C26815](c26815.md) and [C26816](c26816.md). Those warnings are more general versions of this warning.

## Remarks

Expand All @@ -38,7 +40,7 @@ Subtle difference in result types:
gsl::span<const sequence_item> get_seed_sequence() noexcept;

// Returns a generated collection. Doesn't own new data.
const std::vector<sequence_item> get_next_sequence(gsl::span<const sequence_item>);
std::vector<sequence_item> get_next_sequence(gsl::span<const sequence_item>);

void run_batch()
{
Expand All @@ -50,3 +52,9 @@ void run_batch()
}
}
```

To fix the issue, make sure the view is created from an object that lives at least as long as the view itself. Sometimes a solution can be achieved by copying the data, other times some APIs need to be redesigned to share a reference to an object that lives long enough instead of returning a temporary copy.

## See also
[C26815](c26815.md)\
[C26816](c26816.md)
66 changes: 11 additions & 55 deletions docs/code-quality/c26450.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
---
description: "Learn more about: Arithmetic overflow: '%operator%' operation causes overflow at compile time. Use a wider type to store the operands"
title: Warning C26450
ms.date: 01/08/2017
description: "Describes the causes of MSVC code analysis warning C26450 and how to fix it."
ms.date: 05/11/2023
f1_keywords: ["C26450", "RESULT_OF_ARITHMETIC_OPERATION_PROVABLY_LOSSY"]
helpviewer_keywords: ["C26450"]
---
# Warning C26450

>Arithmetic overflow: '*operator*' operation causes overflow at compile time. Use a wider type to store the operands (io.1)
> Arithmetic overflow: '*operator*' operation causes overflow at compile time. Use a wider type to store the operands (io.1)

## Remarks

This warning indicates that an arithmetic operation was provably lossy at compile time. It can be asserted when the operands are all compile-time constants. Currently, we check left shift, multiplication, addition, and subtraction operations for such overflows.

Warning C4307 is a similar check in the Microsoft C++ compiler.
Warning [C4307](../error-messages/compiler-warnings/compiler-warning-level-2-c4307.md) is a similar check in the Microsoft C++ compiler.

Code analysis name: `RESULT_OF_ARITHMETIC_OPERATION_PROVABLY_LOSSY`

## Example 1
## Examples

```cpp
int multiply()
Expand All @@ -36,59 +36,15 @@ long long multiply()
{
const int a = INT_MAX;
const int b = 2;
long long c = (long long)a * b; // OK
return c;
}
```

## Example 2

```cpp
int add()
{
const int a = INT_MAX;
const int b = 2;
int c = a + b; // C26450 reported here
return c;
}
```

To correct this warning, use the following code:

```cpp
long long add()
{
const int a = INT_MAX;
const int b = 2;
long long c = (long long)a + b; // OK
return c;
}
```

## Example 3

```cpp
int subtract()
{
const int a = -INT_MAX;
const int b = 2;
int c = a - b; // C26450 reported here
return c;
}
```

To correct this warning, use the following code.

```cpp
long long subtract()
{
const int a = -INT_MAX;
const int b = 2;
long long c = (long long)a - b; // OK
long long c = static_cast<long long>(a) * b; // OK
return c;
}
```

## See also

[ES.103: Don't overflow](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-overflow)
[26451](c26451.md)\
[26452](c26452.md)\
[26453](c26453.md)\
[26454](c26454.md)\
[ES.103: Don't overflow](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-overflow)
58 changes: 10 additions & 48 deletions docs/code-quality/c26451.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Warning C26451
description: "Describes the causes of MSVC code analysis warning C26451, and shows how to fix it."
ms.date: 07/15/2020
ms.date: 05/11/2023
f1_keywords: ["C26451", "RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE"]
helpviewer_keywords: ["C26451"]
---
Expand All @@ -17,14 +17,14 @@ Code analysis detects when an integral value gets shifted left, multiplied, adde

Code analysis name: `RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE`

## Example 1
## Examples

The following code generates this warning:

```cpp
void leftshift(int i) noexcept
{
unsigned __int64 x;
unsigned long long x;
x = i << 31; // C26451 reported here

// code
Expand All @@ -36,55 +36,17 @@ To correct this warning, use the following code:
```cpp
void leftshift(int i) noexcept
{
unsigned __int64 x;
x = static_cast<unsigned __int64>(i) << 31; // OK
unsigned long long x;
x = static_cast<unsigned long long>(i) << 31; // OK

// code
}
```

## Example 2

```cpp
void somefunc(__int64 /* y */) noexcept
{}

void callsomefunc(int x) noexcept
{
somefunc(x * 2); // C26451 reported here
}
```

To correct this warning, use the following code:

```cpp
void callsomefunc(int x) noexcept
{
somefunc(static_cast<__int64>(x) * 2); // OK
}
```

## Example 3

```cpp
__int64 add(int x) noexcept
{
constexpr auto value = 2;
return x += value; // C26451 reported here
}
```

To correct this warning, use the following code:

```cpp
__int64 add(int x) noexcept
{
constexpr auto value = 2;
const __int64 y = static_cast<__int64>(x) + value; // OK
return y;
}
```

## See also

- [ES.103: Don't overflow](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-overflow)
[26450](c26450.md)\
[26452](c26452.md)\
[26453](c26453.md)\
[26454](c26454.md)\
[ES.103: Don't overflow](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-overflow)
13 changes: 9 additions & 4 deletions docs/code-quality/c26452.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ helpviewer_keywords: ["C26452"]

This warning indicates the shift count is negative, or greater than or equal to the number of bits in the shifted operand. Either case results in undefined behavior.

Warning C4293 is a similar check in the Microsoft C++ compiler.
Warning [C4293](../error-messages/compiler-warnings/compiler-warning-level-1-c4293.md) is a similar check in the Microsoft C++ compiler.

Code analysis name: `SHIFT_COUNT_NEGATIVE_OR_TOO_BIG`

## Example

```cpp
unsigned __int64 combine(unsigned lo, unsigned hi)
unsigned long long combine(unsigned lo, unsigned hi)
{
return (hi << 32) | lo; // C26252 here
}
Expand All @@ -29,12 +29,17 @@ unsigned __int64 combine(unsigned lo, unsigned hi)
To correct this warning, use the following code:

```cpp
unsigned __int64 combine(unsigned lo, unsigned hi)
unsigned long long combine(unsigned lo, unsigned hi)
{
return (static_cast<unsigned __int64>(hi) << 32) | lo; // OK
}
```

## See also

[ES.102: Use signed types for arithmetic](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-unsigned)
[26450](c26450.md)\
[26451](c26451.md)\
[26453](c26453.md)\
[26454](c26454.md)\
[ES.101: Use unsigned types for bit manipulation](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-unsigned)\
[ES.102: Use signed types for arithmetic](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-signed)
Loading