-
Notifications
You must be signed in to change notification settings - Fork 457
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
Add ALWAYS and NEVER macros (from SQLite) #720
Changes from 12 commits
6e21577
34c109a
96dae14
3f9935e
1e5e16b
a940ebe
c09a4b0
f7568cc
da6bbd0
c89c033
6a3dcc3
ae6a3f3
20251d9
6abf4c7
69865a5
ea17da7
d1dcd0a
963fbbb
d6ff321
184836b
98a747a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,7 +24,7 @@ | |
#ifndef ALLOC_H | ||
#define ALLOC_H | ||
|
||
#include "h3api.h" // for TJOIN | ||
#include "h3api.h" // for TJOIN | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file was incorrectly not formatted before |
||
|
||
#ifdef H3_ALLOC_PREFIX | ||
#define H3_MEMORY(name) TJOIN(H3_ALLOC_PREFIX, name) | ||
|
@@ -33,10 +33,10 @@ | |
extern "C" { | ||
#endif | ||
|
||
void* H3_MEMORY(malloc)(size_t size); | ||
void* H3_MEMORY(calloc)(size_t num, size_t size); | ||
void* H3_MEMORY(realloc)(void* ptr, size_t size); | ||
void H3_MEMORY(free)(void* ptr); | ||
void *H3_MEMORY(malloc)(size_t size); | ||
void *H3_MEMORY(calloc)(size_t num, size_t size); | ||
void *H3_MEMORY(realloc)(void *ptr, size_t size); | ||
void H3_MEMORY(free)(void *ptr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why wasn't this previously formatted via clang? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was not included in the list of source files, presumably an oversight. |
||
|
||
#ifdef __cplusplus | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
/* | ||
* Copyright 2022 Uber Technologies, Inc. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
/** @file h3Assert.h | ||
* @brief Support code for unit testing and assertions | ||
* | ||
* This file defines macros needed for defensive programming in the H3 core | ||
* library. H3 strives to have complete code and branch coverage, but this is | ||
* not feasible if some branches cannot be reached because they are defensive - | ||
* that is, we do not know of a test case that would exercise the branch but we | ||
* do have an opinion of how to recover from such an error. These defensive | ||
* branches are excluded from coverage. | ||
* | ||
* In other testing, such as unit tests or fuzzer testing, they trigger | ||
* assertions if the conditions fail. | ||
* | ||
* Adapted from https://www.sqlite.org/testing.html and | ||
* https://www.sqlite.org/assert.html | ||
* | ||
* Used under the terms of the SQLite3 project, reproduced below: | ||
* The author disclaims copyright to this source code. In place of | ||
* a legal notice, here is a blessing: | ||
* | ||
* May you do good and not evil. | ||
* May you find forgiveness for yourself and forgive others. | ||
* May you share freely, never taking more than you give. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is amazing 😮 |
||
*/ | ||
|
||
#ifndef H3ASSERT_H | ||
#define H3ASSERT_H | ||
|
||
#include <assert.h> | ||
|
||
/* | ||
** The testcase() macro is used to aid in coverage testing. When | ||
** doing coverage testing, the condition inside the argument to | ||
** testcase() must be evaluated both true and false in order to | ||
** get full branch coverage. The testcase() macro is inserted | ||
** to help ensure adequate test coverage in places where simple | ||
** condition/decision coverage is inadequate. For example, testcase() | ||
** can be used to make sure boundary values are tested. For | ||
** bitmask tests, testcase() can be used to make sure each bit | ||
** is significant and used at least once. On switch statements | ||
** where multiple cases go to the same block of code, testcase() | ||
** can insure that all cases are evaluated. | ||
*/ | ||
#if defined(H3_COVERAGE_TEST) || defined(H3_DEBUG) | ||
extern unsigned int h3CoverageCounter; | ||
#define testcase(X) \ | ||
if (X) { \ | ||
h3CoverageCounter += (unsigned)__LINE__; \ | ||
} | ||
#else | ||
#define testcase(X) | ||
#endif | ||
|
||
/* | ||
** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage | ||
** and mutation testing | ||
*/ | ||
#if defined(H3_COVERAGE_TEST) | ||
#define H3_OMIT_AUXILIARY_SAFETY_CHECKS 1 | ||
#endif | ||
|
||
/* | ||
** The TESTONLY macro is used to enclose variable declarations or | ||
** other bits of code that are needed to support the arguments | ||
** within testcase() and assert() macros. | ||
*/ | ||
#if !defined(NDEBUG) || defined(H3_COVERAGE_TEST) | ||
#define TESTONLY(X) X | ||
#else | ||
#define TESTONLY(X) | ||
#endif | ||
|
||
/* | ||
** The DEFENSEONLY macro is used to enclose variable declarations or | ||
** other bits of code that are needed to support the arguments | ||
** within ALWAYS() or NEVER() macros. | ||
*/ | ||
#if !defined(H3_OMIT_AUXILIARY_SAFETY_CHECKS) | ||
#define DEFENSEONLY(X) X | ||
#else | ||
#define DEFENSEONLY(X) | ||
#endif | ||
|
||
/* | ||
** The ALWAYS and NEVER macros surround boolean expressions which | ||
** are intended to always be true or false, respectively. Such | ||
** expressions could be omitted from the code completely. But they | ||
** are included in a few cases in order to enhance the resilience | ||
** of SQLite to unexpected behavior - to make the code "self-healing" | ||
isaacbrodsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
** or "ductile" rather than being "brittle" and crashing at the first | ||
** hint of unplanned behavior. | ||
** | ||
** In other words, ALWAYS and NEVER are added for defensive code. | ||
** | ||
** When doing coverage testing ALWAYS and NEVER are hard-coded to | ||
** be true and false so that the unreachable code they specify will | ||
** not be counted as untested code. | ||
*/ | ||
#if defined(H3_OMIT_AUXILIARY_SAFETY_CHECKS) | ||
#define ALWAYS(X) (1) | ||
#define NEVER(X) (0) | ||
#elif !defined(NDEBUG) | ||
#define ALWAYS(X) ((X) ? 1 : (assert(0), 0)) | ||
#define NEVER(X) ((X) ? (assert(0), 1) : 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So I understand, the expression There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conceptually that is correct. |
||
#else | ||
#define ALWAYS(X) (X) | ||
#define NEVER(X) (X) | ||
#endif | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my info, why toggle this?
Oh, I see - this now changes the production build as well? So locally, we should make sure to toggle this ON when developing, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this should be OFF while developing in order to get the benefit of the assertions.